diff options
49 files changed, 2391 insertions, 2854 deletions
diff --git a/.swiftlint.yml b/.swiftlint.yml index 02cc6429b..ac6e392d4 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -10,10 +10,14 @@ empty_count: severity: warning line_length: - # warning: 120 + # warning: 120, error: 200 warning: 250 error: 250 +function_body_length: + # warning: 40 + warning: 60 + type_body_length: # error: 350 error: 500 @@ -106,16 +110,8 @@ excluded: - iOSClient/Select/NCSelect.swift - iOSClient/Settings/NCEndToEndInitialize.swift - iOSClient/Settings/NCManageAutoUploadFileName.swift - - iOSClient/Share/NCShare.swift - - iOSClient/Share/NCShareCommentsCell.swift - iOSClient/Share/NCShareCommon.swift - - iOSClient/Share/NCShareLinkCell.swift - - iOSClient/Share/NCShareLinkMenuView.swift - iOSClient/Share/NCShareNetworking.swift - - iOSClient/Share/NCSharePaging.swift - - iOSClient/Share/NCShareQuickStatusMenu.swift - - iOSClient/Share/NCShareUserCell.swift - - iOSClient/Share/NCShareUserMenuView.swift - iOSClient/Shares/NCShares.swift - iOSClient/Transfers/NCTransferCell.swift - iOSClient/Transfers/NCTransfers.swift diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index 558554528..a52626815 100644 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -45,7 +45,10 @@ AF4BF61F27562B3F0081CEEF /* NCManageDatabase+Activity.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF4BF61D27562B3F0081CEEF /* NCManageDatabase+Activity.swift */; }; AF4BF62027562B3F0081CEEF /* NCManageDatabase+Activity.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF4BF61D27562B3F0081CEEF /* NCManageDatabase+Activity.swift */; }; AF4BF62127562B3F0081CEEF /* NCManageDatabase+Activity.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF4BF61D27562B3F0081CEEF /* NCManageDatabase+Activity.swift */; }; + AF56C1DC2784856200D8BAE2 /* NCActivityCommentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = AF56C1DB2784856200D8BAE2 /* NCActivityCommentView.xib */; }; AF68326A27BE65A90010BF0B /* NCMenuAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF68326927BE65A90010BF0B /* NCMenuAction.swift */; }; + AF70C14D27F3484D00E13DF2 /* SharePermissionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF70C14C27F3484D00E13DF2 /* SharePermissionTest.swift */; }; + AF730AF827834B1400B7520E /* NCShare+NCCellDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF730AF727834B1400B7520E /* NCShare+NCCellDelegate.swift */; }; AF730AFA27843E4C00B7520E /* NCShareExtension+NCDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF730AF927843E4C00B7520E /* NCShareExtension+NCDelegate.swift */; }; AF7E504E27A2D8FF00B5E4AF /* UIBarButton+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF7E504D27A2D8FF00B5E4AF /* UIBarButton+Extension.swift */; }; AF7E505027A2D92300B5E4AF /* NCSelectableNavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF7E504F27A2D92300B5E4AF /* NCSelectableNavigationView.swift */; }; @@ -55,7 +58,20 @@ AF817EF4274BC781009ED85B /* NCUserBaseUrl.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF817EF0274BC781009ED85B /* NCUserBaseUrl.swift */; }; AF8ED1FC2757821000B8DBC4 /* NextcloudTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF8ED1FB2757821000B8DBC4 /* NextcloudTests.swift */; }; AF8ED2032757822700B8DBC4 /* NCGlobalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF8ED2022757822700B8DBC4 /* NCGlobalTests.swift */; }; + AF93471227E2341B002537EE /* NCShare+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF93471127E2341B002537EE /* NCShare+Menu.swift */; }; + AF93471927E2361E002537EE /* NCShareAdvancePermissionFooter.xib in Resources */ = {isa = PBXBuildFile; fileRef = AF93471427E2361E002537EE /* NCShareAdvancePermissionFooter.xib */; }; + AF93471A27E2361E002537EE /* NCShareAdvancePermissionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF93471527E2361E002537EE /* NCShareAdvancePermissionHeader.swift */; }; + AF93471B27E2361E002537EE /* NCShareAdvancePermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF93471627E2361E002537EE /* NCShareAdvancePermission.swift */; }; + AF93471C27E2361E002537EE /* NCShareAdvancePermissionHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = AF93471727E2361E002537EE /* NCShareAdvancePermissionHeader.xib */; }; + AF93471D27E2361E002537EE /* NCShareAdvancePermissionFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF93471827E2361E002537EE /* NCShareAdvancePermissionFooter.swift */; }; + AF93474C27E34120002537EE /* NCUtility+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF93474B27E34120002537EE /* NCUtility+Image.swift */; }; + AF93474E27E3F212002537EE /* NCShareNewUserAddComment.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF93474D27E3F211002537EE /* NCShareNewUserAddComment.swift */; }; AF935067276B84E700BD078F /* NCMenu+FloatingPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF935066276B84E700BD078F /* NCMenu+FloatingPanel.swift */; }; + AFA2AC8527849604008E1EA7 /* NCActivityCommentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA2AC8427849604008E1EA7 /* NCActivityCommentView.swift */; }; + AFCE353327E4ED1900FEA6C2 /* UIToolbar+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353227E4ED1900FEA6C2 /* UIToolbar+Extension.swift */; }; + AFCE353527E4ED5900FEA6C2 /* DateFormatter+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353427E4ED5900FEA6C2 /* DateFormatter+Extension.swift */; }; + AFCE353727E4ED7B00FEA6C2 /* NCShareCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353627E4ED7B00FEA6C2 /* NCShareCells.swift */; }; + AFCE353927E5DE0500FEA6C2 /* NCShare+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */; }; AFD33240276A02C100F5AE02 /* UIApplication+Orientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFD3323F276A02C000F5AE02 /* UIApplication+Orientation.swift */; }; D575039F27146F93008DC9DC /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A0D1342591FBC5008F8A13 /* String+Extensions.swift */; }; D5B6AA7827200C7200D49C24 /* NCActivityTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */; }; @@ -223,10 +239,7 @@ F76673F022C90434007ED366 /* FileProviderUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = F76673EF22C90433007ED366 /* FileProviderUtility.swift */; }; F7682FE023C36B0500983A04 /* NCMainTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7682FDF23C36B0500983A04 /* NCMainTabBar.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 */; }; @@ -258,7 +271,7 @@ F771E3F820E239B500AFB62D /* FileProviderExtension+Thumbnail.swift in Sources */ = {isa = PBXBuildFile; fileRef = F771E3F520E239B400AFB62D /* FileProviderExtension+Thumbnail.swift */; }; F7725A60251F33BB00D125E0 /* NCFiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7725A5E251F33BB00D125E0 /* NCFiles.swift */; }; F7725A61251F33BB00D125E0 /* NCFiles.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7725A5F251F33BB00D125E0 /* NCFiles.storyboard */; }; - F774264A22EB4D0000B23912 /* NCShareUserDropDownCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F774264822EB4D0000B23912 /* NCShareUserDropDownCell.xib */; }; + F774264A22EB4D0000B23912 /* NCSearchUserDropDownCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F774264822EB4D0000B23912 /* NCSearchUserDropDownCell.xib */; }; F77444F522281649000D5EB0 /* NCGridMediaCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F77444F322281649000D5EB0 /* NCGridMediaCell.swift */; }; F77444F622281649000D5EB0 /* NCGridMediaCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F77444F422281649000D5EB0 /* NCGridMediaCell.xib */; }; F77444F8222816D5000D5EB0 /* NCPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F77444F7222816D5000D5EB0 /* NCPickerViewController.swift */; }; @@ -273,7 +286,6 @@ F77B0F611D118A16002130FE /* Acknowledgements.rtf in Resources */ = {isa = PBXBuildFile; fileRef = F7ACE42B1BAC0268006C0017 /* Acknowledgements.rtf */; }; F77B0F631D118A16002130FE /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = F7E70DE91A24DE4100E1B66A /* Localizable.strings */; }; F77B0F7D1D118A16002130FE /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F7F67BB81A24D27800EE80DA /* Images.xcassets */; }; - F77EFC0C26D6751F00806ED6 /* NCShareQuickStatusMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F77EFC0B26D6751F00806ED6 /* NCShareQuickStatusMenu.swift */; }; F78071091EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m in Sources */ = {isa = PBXBuildFile; fileRef = F78071081EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m */; }; F780710A1EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m in Sources */ = {isa = PBXBuildFile; fileRef = F78071081EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m */; }; F78295311F962EFA00A572F5 /* NCEndToEndEncryption.m in Sources */ = {isa = PBXBuildFile; fileRef = F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */; }; @@ -303,8 +315,6 @@ F78F74342163757000C2ADAD /* NCTrash.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F78F74332163757000C2ADAD /* NCTrash.storyboard */; }; F78F74362163781100C2ADAD /* NCTrash.swift in Sources */ = {isa = PBXBuildFile; fileRef = F78F74352163781100C2ADAD /* NCTrash.swift */; }; F790110E21415BF600D7B136 /* NCViewerRichdocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = F790110D21415BF600D7B136 /* NCViewerRichdocument.swift */; }; - F79728D422F96F2E003CACA7 /* NCShareLinkFolderMenuView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F79728D322F96F2D003CACA7 /* NCShareLinkFolderMenuView.xib */; }; - F79728D622F9A0B1003CACA7 /* NCShareUserFolderMenuView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F79728D522F9A0B0003CACA7 /* NCShareUserFolderMenuView.xib */; }; F798F0E225880608000DAFFD /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70CEF5523E9C7E50007035B /* UIColor+Extensions.swift */; }; F798F0E725880609000DAFFD /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70CEF5523E9C7E50007035B /* UIColor+Extensions.swift */; }; F798F0EC2588060A000DAFFD /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70CEF5523E9C7E50007035B /* UIColor+Extensions.swift */; }; @@ -360,7 +370,6 @@ F7D57C8B26317BDE00DE301D /* NCAccountRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7CA212B25F1333200826ABB /* NCAccountRequest.swift */; }; F7D96FCC246ED7E200536D73 /* NCNetworkingCheckRemoteUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7D96FCB246ED7E100536D73 /* NCNetworkingCheckRemoteUser.swift */; }; F7DBC37C23325E02001A85BA /* NCAppConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7DBC37B23325E01001A85BA /* NCAppConfigView.swift */; }; - F7DFAA8A22E22EF100FC4527 /* NCShareLinkMenuView.xib in Resources */ = {isa = PBXBuildFile; fileRef = F7DFAA8922E22EF100FC4527 /* NCShareLinkMenuView.xib */; }; F7DFB7F0219C5B8000680748 /* NCCreateFormUploadAssets.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7DFB7EF219C5B8000680748 /* NCCreateFormUploadAssets.swift */; }; F7DFB7F4219C5CA800680748 /* NCCreateFormUploadScanDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7DFB7F3219C5CA800680748 /* NCCreateFormUploadScanDocument.swift */; }; F7E0CDCF265CE8610044854E /* NCUserStatus.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7E0CDCE265CE8610044854E /* NCUserStatus.storyboard */; }; @@ -402,7 +411,6 @@ F7F4F10A27ECDBDB008676F9 /* Inconsolata-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F7F4F10227ECDBDB008676F9 /* Inconsolata-ExtraBold.ttf */; }; F7F4F10B27ECDBDB008676F9 /* Inconsolata-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F7F4F10327ECDBDB008676F9 /* Inconsolata-Light.ttf */; }; F7F4F10C27ECDBDB008676F9 /* Inconsolata-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F7F4F10427ECDBDB008676F9 /* Inconsolata-Regular.ttf */; }; - F7F4F10E27ECDC3C008676F9 /* UIApplication+Orientation.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F4F10D27ECDC3C008676F9 /* UIApplication+Orientation.swift */; }; F7F4F11027ECDC4A008676F9 /* UIDevice+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F4F10F27ECDC4A008676F9 /* UIDevice+Extensions.swift */; }; F7F4F11227ECDC52008676F9 /* UIFont+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F4F11127ECDC52008676F9 /* UIFont+Extension.swift */; }; F7F878AE1FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F878AD1FB9E3B900599E4F /* NCEndToEndMetadata.swift */; }; @@ -498,7 +506,10 @@ AF4BF613275629E20081CEEF /* NCManageDatabase+Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+Account.swift"; sourceTree = "<group>"; }; AF4BF61827562A4B0081CEEF /* NCManageDatabase+Metadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+Metadata.swift"; sourceTree = "<group>"; }; AF4BF61D27562B3F0081CEEF /* NCManageDatabase+Activity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCManageDatabase+Activity.swift"; sourceTree = "<group>"; }; + AF56C1DB2784856200D8BAE2 /* NCActivityCommentView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NCActivityCommentView.xib; sourceTree = "<group>"; }; AF68326927BE65A90010BF0B /* NCMenuAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMenuAction.swift; sourceTree = "<group>"; }; + AF70C14C27F3484D00E13DF2 /* SharePermissionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharePermissionTest.swift; sourceTree = "<group>"; }; + AF730AF727834B1400B7520E /* NCShare+NCCellDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCShare+NCCellDelegate.swift"; sourceTree = "<group>"; }; AF730AF927843E4C00B7520E /* NCShareExtension+NCDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCShareExtension+NCDelegate.swift"; sourceTree = "<group>"; }; AF7E504D27A2D8FF00B5E4AF /* UIBarButton+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIBarButton+Extension.swift"; sourceTree = "<group>"; }; AF7E504F27A2D92300B5E4AF /* NCSelectableNavigationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCSelectableNavigationView.swift; sourceTree = "<group>"; }; @@ -506,7 +517,20 @@ AF8ED1F92757821000B8DBC4 /* NextcloudTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NextcloudTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; AF8ED1FB2757821000B8DBC4 /* NextcloudTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NextcloudTests.swift; sourceTree = "<group>"; }; AF8ED2022757822700B8DBC4 /* NCGlobalTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCGlobalTests.swift; sourceTree = "<group>"; }; + AF93471127E2341B002537EE /* NCShare+Menu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCShare+Menu.swift"; sourceTree = "<group>"; }; + AF93471427E2361E002537EE /* NCShareAdvancePermissionFooter.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCShareAdvancePermissionFooter.xib; sourceTree = "<group>"; }; + AF93471527E2361E002537EE /* NCShareAdvancePermissionHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCShareAdvancePermissionHeader.swift; sourceTree = "<group>"; }; + AF93471627E2361E002537EE /* NCShareAdvancePermission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCShareAdvancePermission.swift; sourceTree = "<group>"; }; + AF93471727E2361E002537EE /* NCShareAdvancePermissionHeader.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCShareAdvancePermissionHeader.xib; sourceTree = "<group>"; }; + AF93471827E2361E002537EE /* NCShareAdvancePermissionFooter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCShareAdvancePermissionFooter.swift; sourceTree = "<group>"; }; + AF93474B27E34120002537EE /* NCUtility+Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCUtility+Image.swift"; sourceTree = "<group>"; }; + AF93474D27E3F211002537EE /* NCShareNewUserAddComment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCShareNewUserAddComment.swift; sourceTree = "<group>"; }; AF935066276B84E700BD078F /* NCMenu+FloatingPanel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCMenu+FloatingPanel.swift"; sourceTree = "<group>"; }; + AFA2AC8427849604008E1EA7 /* NCActivityCommentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCActivityCommentView.swift; sourceTree = "<group>"; }; + AFCE353227E4ED1900FEA6C2 /* UIToolbar+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIToolbar+Extension.swift"; sourceTree = "<group>"; }; + AFCE353427E4ED5900FEA6C2 /* DateFormatter+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DateFormatter+Extension.swift"; sourceTree = "<group>"; }; + AFCE353627E4ED7B00FEA6C2 /* NCShareCells.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCShareCells.swift; sourceTree = "<group>"; }; + AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NCShare+Helper.swift"; sourceTree = "<group>"; }; AFD3323F276A02C000F5AE02 /* UIApplication+Orientation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIApplication+Orientation.swift"; sourceTree = "<group>"; }; D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCActivityTableViewCell.swift; sourceTree = "<group>"; }; F700222B1EC479840080073F /* Custom.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Custom.xcassets; sourceTree = "<group>"; }; @@ -705,10 +729,7 @@ F76673EF22C90433007ED366 /* FileProviderUtility.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileProviderUtility.swift; sourceTree = "<group>"; }; F7682FDF23C36B0500983A04 /* NCMainTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMainTabBar.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>"; }; @@ -729,7 +750,7 @@ F7725A5E251F33BB00D125E0 /* NCFiles.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCFiles.swift; sourceTree = "<group>"; }; F7725A5F251F33BB00D125E0 /* NCFiles.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = NCFiles.storyboard; sourceTree = "<group>"; }; F774264022EB3F7300B23912 /* DropDown.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DropDown.framework; path = Carthage/Build/iOS/DropDown.framework; sourceTree = "<group>"; }; - F774264822EB4D0000B23912 /* NCShareUserDropDownCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCShareUserDropDownCell.xib; sourceTree = "<group>"; }; + F774264822EB4D0000B23912 /* NCSearchUserDropDownCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCSearchUserDropDownCell.xib; sourceTree = "<group>"; }; F77438EB1FCD694900662C46 /* ka-GE */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ka-GE"; path = "ka-GE.lproj/Localizable.strings"; sourceTree = "<group>"; }; F77438F21FCD69D300662C46 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Localizable.strings; sourceTree = "<group>"; }; F77438F91FCD6A0D00662C46 /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/Localizable.strings"; sourceTree = "<group>"; }; @@ -754,7 +775,6 @@ F77910A425DD517B00CEDB9E /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; }; F77910AA25DD53C700CEDB9E /* NCSettingsBundleHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCSettingsBundleHelper.swift; sourceTree = "<group>"; }; F77A697C250A0FBC00FF1708 /* NCCollectionViewCommon+Menu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NCCollectionViewCommon+Menu.swift"; sourceTree = "<group>"; }; - F77EFC0B26D6751F00806ED6 /* NCShareQuickStatusMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCShareQuickStatusMenu.swift; sourceTree = "<group>"; }; F78071071EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+MainThread.h"; sourceTree = "<group>"; }; F78071081EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSNotificationCenter+MainThread.m"; sourceTree = "<group>"; }; F785EE9C246196DF00B3F945 /* NCNetworkingE2EE.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCNetworkingE2EE.swift; sourceTree = "<group>"; }; @@ -778,8 +798,6 @@ F78F74352163781100C2ADAD /* NCTrash.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCTrash.swift; sourceTree = "<group>"; }; F790110D21415BF600D7B136 /* NCViewerRichdocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCViewerRichdocument.swift; sourceTree = "<group>"; }; F79018A424092EF4007C9B6D /* ATGMediaBrowser.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ATGMediaBrowser.framework; path = Carthage/Build/iOS/ATGMediaBrowser.framework; sourceTree = "<group>"; }; - F79728D322F96F2D003CACA7 /* NCShareLinkFolderMenuView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCShareLinkFolderMenuView.xib; sourceTree = "<group>"; }; - F79728D522F9A0B0003CACA7 /* NCShareUserFolderMenuView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCShareUserFolderMenuView.xib; sourceTree = "<group>"; }; F79918A021997F9000C2E308 /* UICKeyChainStore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UICKeyChainStore.framework; path = Carthage/Build/iOS/UICKeyChainStore.framework; sourceTree = "<group>"; }; F79918A72199840500C2E308 /* Sheeeeeeeeet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sheeeeeeeeet.framework; path = Carthage/Build/iOS/Sheeeeeeeeet.framework; sourceTree = "<group>"; }; F79A65C22191D90F00FF6DCC /* NCSelect.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCSelect.storyboard; sourceTree = "<group>"; }; @@ -898,7 +916,6 @@ F7DBC37B23325E01001A85BA /* NCAppConfigView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCAppConfigView.swift; sourceTree = "<group>"; }; F7DBD82B23E46A4700ECB7C6 /* MarkdownKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MarkdownKit.framework; path = Carthage/Build/iOS/MarkdownKit.framework; sourceTree = "<group>"; }; F7DE9AB01F482FA5008DFE10 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = "<group>"; }; - F7DFAA8922E22EF100FC4527 /* NCShareLinkMenuView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NCShareLinkMenuView.xib; sourceTree = "<group>"; }; F7DFB7EF219C5B8000680748 /* NCCreateFormUploadAssets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCreateFormUploadAssets.swift; sourceTree = "<group>"; }; F7DFB7F3219C5CA800680748 /* NCCreateFormUploadScanDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCreateFormUploadScanDocument.swift; sourceTree = "<group>"; }; F7E0CDCE265CE8610044854E /* NCUserStatus.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCUserStatus.storyboard; sourceTree = "<group>"; }; @@ -924,7 +941,6 @@ F7F4F10227ECDBDB008676F9 /* Inconsolata-ExtraBold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Inconsolata-ExtraBold.ttf"; sourceTree = "<group>"; }; F7F4F10327ECDBDB008676F9 /* Inconsolata-Light.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Inconsolata-Light.ttf"; sourceTree = "<group>"; }; F7F4F10427ECDBDB008676F9 /* Inconsolata-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Inconsolata-Regular.ttf"; sourceTree = "<group>"; }; - F7F4F10D27ECDC3C008676F9 /* UIApplication+Orientation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIApplication+Orientation.swift"; sourceTree = "<group>"; }; F7F4F10F27ECDC4A008676F9 /* UIDevice+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIDevice+Extensions.swift"; sourceTree = "<group>"; }; F7F4F11127ECDC52008676F9 /* UIFont+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIFont+Extension.swift"; sourceTree = "<group>"; }; F7F67BB81A24D27800EE80DA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; }; @@ -1043,6 +1059,7 @@ F7581D2325EFDDDF004DC699 /* NCMedia+Menu.swift */, F7CBC31B24F78E79004D3812 /* NCSortMenu.swift */, F75D19E225EFE09000D74598 /* NCTrash+Menu.swift */, + AF93471127E2341B002537EE /* NCShare+Menu.swift */, F710D2012405826100A6033D /* NCViewer+Menu.swift */, ); path = Menu; @@ -1053,11 +1070,26 @@ children = ( AF8ED2022757822700B8DBC4 /* NCGlobalTests.swift */, AF36077527BFB019001A243D /* ParallelWorkerTest.swift */, + AF70C14C27F3484D00E13DF2 /* SharePermissionTest.swift */, AF8ED1FB2757821000B8DBC4 /* NextcloudTests.swift */, ); path = NextcloudTests; sourceTree = "<group>"; }; + AF93471327E235EB002537EE /* Advanced */ = { + isa = PBXGroup; + children = ( + AF93471627E2361E002537EE /* NCShareAdvancePermission.swift */, + AFCE353627E4ED7B00FEA6C2 /* NCShareCells.swift */, + AF93471827E2361E002537EE /* NCShareAdvancePermissionFooter.swift */, + AF93471427E2361E002537EE /* NCShareAdvancePermissionFooter.xib */, + AF93474D27E3F211002537EE /* NCShareNewUserAddComment.swift */, + AF93471527E2361E002537EE /* NCShareAdvancePermissionHeader.swift */, + AF93471727E2361E002537EE /* NCShareAdvancePermissionHeader.xib */, + ); + path = Advanced; + sourceTree = "<group>"; + }; F70211F31BAC56E9003FC03E /* Main */ = { isa = PBXGroup; children = ( @@ -1191,24 +1223,20 @@ children = ( F700510022DF63AC003A3356 /* NCShare.storyboard */, F700510422DF6A89003A3356 /* NCShare.swift */, + AFCE353827E5DE0400FEA6C2 /* NCShare+Helper.swift */, + AF730AF727834B1400B7520E /* NCShare+NCCellDelegate.swift */, + AF93471327E235EB002537EE /* Advanced */, F723B3DC22FC6D1C00301EFE /* NCShareCommentsCell.xib */, F7E4D9C322ED929B003675FD /* NCShareCommentsCell.swift */, F769454522E9F1B0000A798A /* NCShareCommon.swift */, F73CB3B122E072A000AD728E /* NCShareHeaderView.xib */, F787704E22E7019900F287A9 /* NCShareLinkCell.xib */, AF2D7C7B2742556F00ADF566 /* NCShareLinkCell.swift */, - F79728D322F96F2D003CACA7 /* NCShareLinkFolderMenuView.xib */, - F769454122E9F0EE000A798A /* NCShareLinkMenuView.swift */, - F7DFAA8922E22EF100FC4527 /* NCShareLinkMenuView.xib */, F769454722E9F20D000A798A /* NCShareNetworking.swift */, F769453F22E9F077000A798A /* NCSharePaging.swift */, - F77EFC0B26D6751F00806ED6 /* NCShareQuickStatusMenu.swift */, + F774264822EB4D0000B23912 /* NCSearchUserDropDownCell.xib */, F769453B22E9CFFF000A798A /* NCShareUserCell.xib */, AF2D7C7D2742559100ADF566 /* NCShareUserCell.swift */, - F774264822EB4D0000B23912 /* NCShareUserDropDownCell.xib */, - F79728D522F9A0B0003CACA7 /* NCShareUserFolderMenuView.xib */, - F769453D22E9E97D000A798A /* NCShareUserMenuView.xib */, - F769454322E9F142000A798A /* NCShareUserMenuView.swift */, ); path = Share; sourceTree = "<group>"; @@ -1432,9 +1460,10 @@ F78071071EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.h */, F78071081EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m */, F7A0D1342591FBC5008F8A13 /* String+Extensions.swift */, - AF1A9B6327D0CA1E00F17A9E /* UIAlertController+Extension.swift */, AFD3323F276A02C000F5AE02 /* UIApplication+Orientation.swift */, - F7F4F10D27ECDC3C008676F9 /* UIApplication+Orientation.swift */, + AFCE353227E4ED1900FEA6C2 /* UIToolbar+Extension.swift */, + AF1A9B6327D0CA1E00F17A9E /* UIAlertController+Extension.swift */, + AFCE353427E4ED5900FEA6C2 /* DateFormatter+Extension.swift */, AF7E504D27A2D8FF00B5E4AF /* UIBarButton+Extension.swift */, F70CEF5523E9C7E50007035B /* UIColor+Extensions.swift */, F79B645F26CA661600838ACA /* UIControl+Extensions.swift */, @@ -1460,7 +1489,9 @@ isa = PBXGroup; children = ( F7C9555221F0C4CA0024296E /* NCActivity.storyboard */, + AF56C1DB2784856200D8BAE2 /* NCActivityCommentView.xib */, F7C9555421F0C5470024296E /* NCActivity.swift */, + AFA2AC8427849604008E1EA7 /* NCActivityCommentView.swift */, D5B6AA7727200C7200D49C24 /* NCActivityTableViewCell.swift */, ); path = Activity; @@ -1548,6 +1579,7 @@ F70968A324212C4E00ED60E5 /* NCLivePhoto.swift */, F707C26421A2DC5200F6181E /* NCStoreReview.swift */, F70BFC7320E0FA7C00C67599 /* NCUtility.swift */, + AF93474B27E34120002537EE /* NCUtility+Image.swift */, AF817EF0274BC781009ED85B /* NCUserBaseUrl.swift */, F74AF3A3247FB6AE00AC767B /* NCUtilityFileSystem.swift */, AF36077027BFA4E8001A243D /* ParallelWorker.swift */, @@ -2247,7 +2279,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - F79728D422F96F2E003CACA7 /* NCShareLinkFolderMenuView.xib in Resources */, F7362A1F220C853A005101B5 /* LaunchScreen.storyboard in Resources */, F77444F622281649000D5EB0 /* NCGridMediaCell.xib in Resources */, F78ACD4421903CF20088454D /* NCListCell.xib in Resources */, @@ -2271,9 +2302,11 @@ F7226EDC1EE4089300EBECB1 /* Main.storyboard in Resources */, F7EFC0C6256BC77700461AAD /* NCMoreUserCell.xib in Resources */, F702F2E725EE5C86008F8E80 /* NCAudioRecorderViewController.storyboard in Resources */, + AF56C1DC2784856200D8BAE2 /* NCActivityCommentView.xib in Resources */, F7632FBF21832F8700721B71 /* NCTrashSectionHeaderMenu.xib in Resources */, F7F4F10B27ECDBDB008676F9 /* Inconsolata-Light.ttf in Resources */, 3704EB2A23D5A58400455C5B /* NCMenu.storyboard in Resources */, + AF93471C27E2361E002537EE /* NCShareAdvancePermissionHeader.xib in Resources */, F7D0F33E264144FC0097D4A3 /* Background.xcassets in Resources */, F7F1E54C2492369A00E42386 /* NCMediaCommandView.xib in Resources */, F710E8111EF95C9C00DC2427 /* ImagesIntro.xcassets in Resources */, @@ -2285,12 +2318,12 @@ F7381EE5218218C9000B1560 /* NCOffline.storyboard in Resources */, F7E0CDCF265CE8610044854E /* NCUserStatus.storyboard in Resources */, F76D3CF32428B94E005DFA87 /* NCViewerPDFSearchCell.xib in Resources */, - F769453E22E9E97E000A798A /* NCShareUserMenuView.xib in Resources */, F7CA212E25F1333300826ABB /* NCAccountRequest.storyboard in Resources */, F749C10E23C4A5340027D966 /* NCIntroCollectionViewCell.xib in Resources */, F717402D24F699A5000C87D5 /* NCFavorite.storyboard in Resources */, F723B3DD22FC6D1D00301EFE /* NCShareCommentsCell.xib in Resources */, F78ACD4B21903F850088454D /* NCTrashListCell.xib in Resources */, + AF93471927E2361E002537EE /* NCShareAdvancePermissionFooter.xib in Resources */, F7725A61251F33BB00D125E0 /* NCFiles.storyboard in Resources */, F700510122DF63AC003A3356 /* NCShare.storyboard in Resources */, F787704F22E7019900F287A9 /* NCShareLinkCell.xib in Resources */, @@ -2303,8 +2336,6 @@ F7651A8A23A2A3F2001403D2 /* NCCreateFormUploadDocuments.storyboard in Resources */, F7F4F10A27ECDBDB008676F9 /* Inconsolata-ExtraBold.ttf in Resources */, F704B5E72430C06700632F5F /* NCCreateFormUploadConflictCell.xib in Resources */, - F79728D622F9A0B1003CACA7 /* NCShareUserFolderMenuView.xib in Resources */, - F7DFAA8A22E22EF100FC4527 /* NCShareLinkMenuView.xib in Resources */, F7C9555321F0C4CA0024296E /* NCActivity.storyboard in Resources */, F7BC287E26663F6C004D46C5 /* NCViewCertificateDetails.storyboard in Resources */, F78ACD54219047D40088454D /* NCSectionFooter.xib in Resources */, @@ -2318,7 +2349,7 @@ F7D1612023CF19E30039EBBF /* NCViewerRichWorkspace.storyboard in Resources */, F77B0F631D118A16002130FE /* Localizable.strings in Resources */, F7632FC1218353AA00721B71 /* NCTrashSectionFooter.xib in Resources */, - F774264A22EB4D0000B23912 /* NCShareUserDropDownCell.xib in Resources */, + F774264A22EB4D0000B23912 /* NCSearchUserDropDownCell.xib in Resources */, F7CB689A2541676B0050EC94 /* NCMore.storyboard in Resources */, F70B866D2642A21300ED5349 /* NCBackgroundImageColor.storyboard in Resources */, F77B0F7D1D118A16002130FE /* Images.xcassets in Resources */, @@ -2405,6 +2436,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + AF70C14D27F3484D00E13DF2 /* SharePermissionTest.swift in Sources */, AF36077627BFB019001A243D /* ParallelWorkerTest.swift in Sources */, AF8ED1FC2757821000B8DBC4 /* NextcloudTests.swift in Sources */, AF8ED2032757822700B8DBC4 /* NCGlobalTests.swift in Sources */, @@ -2523,6 +2555,7 @@ F73F537F1E929C8500F8678D /* NCMore.swift in Sources */, F702F2CF25EE5B5C008F8E80 /* NCGlobal.swift in Sources */, F72CD63A25C19EBF00F46F9A /* NCAutoUpload.swift in Sources */, + AF93471D27E2361E002537EE /* NCShareAdvancePermissionFooter.swift in Sources */, F7DFB7F0219C5B8000680748 /* NCCreateFormUploadAssets.swift in Sources */, AF1A9B6427D0CA1E00F17A9E /* UIAlertController+Extension.swift in Sources */, F73B422C2476764F00A30FD3 /* NCNotification.swift in Sources */, @@ -2538,7 +2571,9 @@ F77910AB25DD53C700CEDB9E /* NCSettingsBundleHelper.swift in Sources */, AF4BF61927562A4B0081CEEF /* NCManageDatabase+Metadata.swift in Sources */, F78A18B623CDD07D00F681F3 /* NCViewerRichWorkspaceWebView.swift in Sources */, + AFA2AC8527849604008E1EA7 /* NCActivityCommentView.swift in Sources */, F716B75F26F09DF600D37EFC /* NCKTVHTTPCache.swift in Sources */, + AFCE353727E4ED7B00FEA6C2 /* NCShareCells.swift in Sources */, AF36077127BFA4E8001A243D /* ParallelWorker.swift in Sources */, F75A9EE623796C6F0044CFCE /* NCNetworking.swift in Sources */, F758B460212C56A400515F55 /* NCScan.swift in Sources */, @@ -2550,9 +2585,9 @@ F72928A0253B0937009CA4FD /* NCMainNavigationController.swift in Sources */, F704B5E92430C0B800632F5F /* NCCreateFormUploadConflictCell.swift in Sources */, F72D404923D2082500A97FD0 /* NCViewerNextcloudText.swift in Sources */, + AFCE353927E5DE0500FEA6C2 /* NCShare+Helper.swift in Sources */, F700510522DF6A89003A3356 /* NCShare.swift in Sources */, F72D1007210B6882009C96B7 /* NCPushNotificationEncryption.m in Sources */, - F769454222E9F0EE000A798A /* NCShareLinkMenuView.swift in Sources */, F785EE9D246196DF00B3F945 /* NCNetworkingE2EE.swift in Sources */, F76673ED22C901F6007ED366 /* FileProviderDomain.swift in Sources */, F7A321AD1E9E6AD50069AD1B /* CCAdvanced.m in Sources */, @@ -2567,6 +2602,7 @@ F7A0D1352591FBC5008F8A13 /* String+Extensions.swift in Sources */, F77B0E5F1D118A16002130FE /* NCSettings.m in Sources */, F7F9D1BB25397CE000D9BFF5 /* NCViewer.swift in Sources */, + AF730AF827834B1400B7520E /* NCShare+NCCellDelegate.swift in Sources */, F70460522499061800BB98A7 /* NotificationCenter+MainThread.swift in Sources */, F78F74362163781100C2ADAD /* NCTrash.swift in Sources */, AF817EF1274BC781009ED85B /* NCUserBaseUrl.swift in Sources */, @@ -2576,10 +2612,12 @@ F74AF3A4247FB6AE00AC767B /* NCUtilityFileSystem.swift in Sources */, F7417DB3216CE925007D05F5 /* NCTrashSectionHeaderFooter.swift in Sources */, F7239871253D86B600257F49 /* NCEmptyDataSet.swift in Sources */, + AFCE353327E4ED1900FEA6C2 /* UIToolbar+Extension.swift in Sources */, 8491B1CD273BBA82001C8C5B /* UIViewController+Menu.swift in Sources */, F702F2F725EE5CED008F8E80 /* NCLogin.swift in Sources */, F7E98C1627E0D0FC001F9F19 /* NCManageDatabase+Video.swift in Sources */, F7F4F11227ECDC52008676F9 /* UIFont+Extension.swift in Sources */, + AF93471A27E2361E002537EE /* NCShareAdvancePermissionHeader.swift in Sources */, F7F878AE1FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */, F7DBC37C23325E02001A85BA /* NCAppConfigView.swift in Sources */, 3781B9B023DB2B7E006B4B1D /* AppDelegate+Menu.swift in Sources */, @@ -2592,6 +2630,7 @@ F7C1EEA525053A9C00866ACC /* NCDataSource.swift in Sources */, F713FF002472764100214AF6 /* UIImage+animatedGIF.m in Sources */, F749C10B23C4A5340027D966 /* NCIntroCollectionViewCell.swift in Sources */, + AFCE353527E4ED5900FEA6C2 /* DateFormatter+Extension.swift in Sources */, F718C24E254D507B00C5C256 /* NCViewerMediaDetailView.swift in Sources */, F7381EE1218218C9000B1560 /* NCOffline.swift in Sources */, F78071091EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m in Sources */, @@ -2599,12 +2638,13 @@ F7CA212D25F1333300826ABB /* NCAccountRequest.swift in Sources */, F765F73125237E3F00391DBE /* NCRecent.swift in Sources */, F76B3CCE1EAE01BD00921AC9 /* NCBrand.swift in Sources */, - F769454422E9F142000A798A /* NCShareUserMenuView.swift in Sources */, F7581D2425EFDDDF004DC699 /* NCMedia+Menu.swift in Sources */, F738D4902756740100CD1D38 /* NCLoginNavigationController.swift in Sources */, F77B0E981D118A16002130FE /* CCManageAccount.m in Sources */, - F77EFC0C26D6751F00806ED6 /* NCShareQuickStatusMenu.swift in Sources */, + AF93474C27E34120002537EE /* NCUtility+Image.swift in Sources */, F702F30125EE5D2C008F8E80 /* NYMnemonic.m in Sources */, + AF93474E27E3F212002537EE /* NCShareNewUserAddComment.swift in Sources */, + AF93471227E2341B002537EE /* NCShare+Menu.swift in Sources */, F7EFA47825ADBA500083159A /* NCViewerProviderContextMenu.swift in Sources */, F755BD9B20594AC7008C5FBB /* NCService.swift in Sources */, AFD33240276A02C100F5AE02 /* UIApplication+Orientation.swift in Sources */, @@ -2620,6 +2660,7 @@ F79A65C62191D95E00FF6DCC /* NCSelect.swift in Sources */, F75D19E325EFE09000D74598 /* NCTrash+Menu.swift in Sources */, F70CAE3A1F8CF31A008125FD /* NCEndToEndEncryption.m in Sources */, + AF93471B27E2361E002537EE /* NCShareAdvancePermission.swift in Sources */, F70753EB2542A99800972D44 /* NCViewerMediaPage.swift in Sources */, F74C0436253F1CDC009762AB /* NCShares.swift in Sources */, F7AE00F5230D5F9E007ACF8A /* NCLoginWeb.swift in Sources */, @@ -2630,7 +2671,6 @@ F702F2E625EE5C86008F8E80 /* NCAudioRecorderViewController.swift in Sources */, D5B6AA7827200C7200D49C24 /* NCActivityTableViewCell.swift in Sources */, F745B253222D88AE00346520 /* NCLoginQRCode.swift in Sources */, - F7F4F10E27ECDC3C008676F9 /* UIApplication+Orientation.swift in Sources */, F7CBC31C24F78E79004D3812 /* NCSortMenu.swift in Sources */, F769454822E9F20D000A798A /* NCShareNetworking.swift in Sources */, F7C9555521F0C5470024296E /* NCActivity.swift in Sources */, @@ -3249,8 +3289,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/nextcloud/ios-communication-library/"; requirement = { - kind = exactVersion; - version = 0.99.5; + branch = develop; + kind = branch; }; }; F788ECC5263AAAF900ADC67F /* XCRemoteSwiftPackageReference "MarkdownKit" */ = { diff --git a/NextcloudTests/SharePermissionTest.swift b/NextcloudTests/SharePermissionTest.swift new file mode 100644 index 000000000..919941eb4 --- /dev/null +++ b/NextcloudTests/SharePermissionTest.swift @@ -0,0 +1,136 @@ +// +// SharePermissionTest.swift +// Nextcloud +// +// Created by Henrik Storch on 29.03.22. +// Copyright © 2021 Henrik Storch. All rights reserved. +// +// Author Henrik Storch <henrik.storch@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/>. +// + +@testable import Nextcloud +import XCTest +import NCCommunication + +class SharePermissionTest: XCTestCase { + override func setUp() { + let json = + """ + {"ocs":{"data":{"capabilities":{"files_sharing":{"default_permissions":31}}}}} + """.data(using: .utf8)! + NCManageDatabase.shared.addCapabilitiesJSon(json, account: "") + } + + func testShareCellPermissionCell() throws { + let share = NCTableShareOptions(sharee: NCCommunicationSharee(), metadata: tableMetadata(), password: nil) + let shareConfig = NCShareConfig(parentMetadata: tableMetadata(), share: share) + + for row in 0..<shareConfig.permissions.count { + guard let cell = shareConfig.config(for: IndexPath(row: row, section: 0)) as? NCToggleCellConfig else { + XCTFail("Invalid share permission cell") + continue + } + XCTAssertFalse(cell.isOn(for: share)) + } + + let meta = tableMetadata() + meta.sharePermissionsCollaborationServices = 31 + let fullShare = NCTableShareOptions(sharee: NCCommunicationSharee(), metadata: meta, password: nil) + let shareFullConfig = NCShareConfig(parentMetadata: meta, share: fullShare) + + for row in 0..<shareFullConfig.permissions.count { + guard let cell = shareConfig.config(for: IndexPath(row: row, section: 0)) as? NCToggleCellConfig else { + XCTFail("Invalid share permission cell") + continue + } + XCTAssertTrue(cell.isOn(for: fullShare)) + } + } + + func testSharePermission() throws { + XCTAssertTrue(NCLinkPermission.allowEdit.hasResharePermission(for: 15)) + XCTAssertTrue(NCLinkPermission.allowEdit.hasResharePermission(for: 11)) + XCTAssertTrue(NCLinkPermission.allowEdit.hasResharePermission(for: 7)) + XCTAssertFalse(NCLinkPermission.allowEdit.hasResharePermission(for: 13)) + XCTAssertFalse(NCLinkPermission.allowEdit.hasResharePermission(for: 1)) + + XCTAssertTrue(NCLinkPermission.viewOnly.hasResharePermission(for: 25)) + XCTAssertTrue(NCLinkPermission.viewOnly.hasResharePermission(for: 17)) + XCTAssertFalse(NCLinkPermission.viewOnly.hasResharePermission(for: 12)) + XCTAssertFalse(NCLinkPermission.viewOnly.hasResharePermission(for: 2)) + + XCTAssertTrue(NCLinkPermission.fileDrop.hasResharePermission(for: 4)) + XCTAssertFalse(NCLinkPermission.fileDrop.hasResharePermission(for: 27)) + + XCTAssertTrue(NCUserPermission.create.hasResharePermission(for: 4)) + XCTAssertFalse(NCUserPermission.create.hasResharePermission(for: 27)) + + XCTAssertTrue(NCUserPermission.edit.hasResharePermission(for: 2)) + XCTAssertFalse(NCUserPermission.edit.hasResharePermission(for: 29)) + + XCTAssertTrue(NCUserPermission.reshare.hasResharePermission(for: 16)) + XCTAssertFalse(NCUserPermission.reshare.hasResharePermission(for: 15)) + } + + func testFileShare() throws { + let meta = tableMetadata() + meta.directory = false + let share = NCTableShareOptions.shareLink(metadata: meta, password: nil) + let fileConfig = NCShareConfig(parentMetadata: meta, share: share) + XCTAssertEqual(fileConfig.advanced, NCShareDetails.forLink) + XCTAssertEqual(fileConfig.permissions as? [NCLinkPermission], NCLinkPermission.forFile) + + meta.directory = true + let folderConfig = NCShareConfig(parentMetadata: meta, share: share) + XCTAssertEqual(folderConfig.advanced, NCShareDetails.forLink) + XCTAssertEqual(folderConfig.permissions as? [NCLinkPermission], NCLinkPermission.forDirectory) + } + + func testUserShare() throws { + let meta = tableMetadata() + meta.directory = false + let sharee = NCCommunicationSharee() + let share = NCTableShareOptions(sharee: sharee, metadata: meta, password: nil) + let fileConfig = NCShareConfig(parentMetadata: meta, share: share) + XCTAssertEqual(fileConfig.advanced, NCShareDetails.forUser) + XCTAssertEqual(fileConfig.permissions as? [NCUserPermission], NCUserPermission.forFile) + + meta.directory = true + let folderConfig = NCShareConfig(parentMetadata: meta, share: share) + XCTAssertEqual(folderConfig.advanced, NCShareDetails.forUser) + XCTAssertEqual(folderConfig.permissions as? [NCUserPermission], NCUserPermission.forDirectory) + } + + func testResharePermission() throws { + let meta = tableMetadata() + let permissionReadShare = NCGlobal.shared.permissionShareShare + NCGlobal.shared.permissionReadShare + meta.sharePermissionsCollaborationServices = permissionReadShare + meta.directory = false + let share = NCTableShareOptions.shareLink(metadata: meta, password: nil) + let fileConfig = NCShareConfig(parentMetadata: meta, share: share) + XCTAssertEqual(fileConfig.resharePermission, meta.sharePermissionsCollaborationServices) + XCTAssertEqual(fileConfig.advanced, NCShareDetails.forLink) + XCTAssertEqual(fileConfig.permissions as? [NCLinkPermission], NCLinkPermission.forFile) + + meta.directory = true + let sharee = NCCommunicationSharee() + let folderShare = NCTableShareOptions(sharee: sharee, metadata: meta, password: nil) + let folderConfig = NCShareConfig(parentMetadata: meta, share: folderShare) + XCTAssertEqual(folderConfig.resharePermission, meta.sharePermissionsCollaborationServices) + XCTAssertEqual(folderConfig.advanced, NCShareDetails.forUser) + XCTAssertEqual(folderConfig.permissions as? [NCUserPermission], NCUserPermission.forDirectory) + } +} diff --git a/iOSClient/Activity/NCActivity.storyboard b/iOSClient/Activity/NCActivity.storyboard index 39c8ecb24..6e9486484 100644 --- a/iOSClient/Activity/NCActivity.storyboard +++ b/iOSClient/Activity/NCActivity.storyboard @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="nhT-TJ-YvX"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="nhT-TJ-YvX"> <device id="retina6_1" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> @@ -17,7 +17,7 @@ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="20" sectionFooterHeight="1" translatesAutoresizingMaskIntoConstraints="NO" id="X49-xg-JXO"> - <rect key="frame" x="0.0" y="100" width="414" height="762"/> + <rect key="frame" x="0.0" y="44" width="414" height="818"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <prototypes> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="tableCell" rowHeight="120" id="ggj-aE-fnh" customClass="NCActivityTableViewCell" customModule="Nextcloud" customModuleProvider="target"> @@ -113,66 +113,18 @@ <outlet property="prefetchDataSource" destination="nhT-TJ-YvX" id="317-AD-uQe"/> </connections> </tableView> - <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sG1-7f-3rF"> - <rect key="frame" x="0.0" y="0.0" width="414" height="100"/> - <subviews> - <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="hVn-Fn-7td"> - <rect key="frame" x="10" y="10" width="40" height="40"/> - <constraints> - <constraint firstAttribute="height" constant="40" id="eRU-q6-wZT"/> - <constraint firstAttribute="width" constant="40" id="nee-e2-atl"/> - </constraints> - </imageView> - <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" clearButtonMode="always" translatesAutoresizingMaskIntoConstraints="NO" id="Wz7-gw-foA"> - <rect key="frame" x="60" y="60" width="344" height="30"/> - <constraints> - <constraint firstAttribute="height" constant="30" id="4ni-Qx-ber"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="14"/> - <textInputTraits key="textInputTraits"/> - <connections> - <action selector="newCommentFieldDidEndOnExitWithTextField:" destination="nhT-TJ-YvX" eventType="editingDidEndOnExit" id="vPB-Eu-qkb"/> - </connections> - </textField> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="user" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YRy-AS-CMk"> - <rect key="frame" x="60" y="21.5" width="344" height="17"/> - <fontDescription key="fontDescription" type="system" pointSize="14"/> - <color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - <nil key="highlightedColor"/> - </label> - </subviews> - <constraints> - <constraint firstItem="YRy-AS-CMk" firstAttribute="centerY" secondItem="hVn-Fn-7td" secondAttribute="centerY" id="CBB-vi-6Z1"/> - <constraint firstAttribute="trailing" secondItem="Wz7-gw-foA" secondAttribute="trailing" constant="10" id="CuV-5o-sFz"/> - <constraint firstItem="hVn-Fn-7td" firstAttribute="leading" secondItem="sG1-7f-3rF" secondAttribute="leading" constant="10" id="NWH-NK-FjI"/> - <constraint firstAttribute="height" constant="100" id="SfP-Sr-vbR"/> - <constraint firstItem="Wz7-gw-foA" firstAttribute="leading" secondItem="hVn-Fn-7td" secondAttribute="trailing" constant="10" id="baP-t5-Kut"/> - <constraint firstItem="Wz7-gw-foA" firstAttribute="top" secondItem="hVn-Fn-7td" secondAttribute="bottom" constant="10" id="bsh-yh-NR2"/> - <constraint firstItem="YRy-AS-CMk" firstAttribute="leading" secondItem="hVn-Fn-7td" secondAttribute="trailing" constant="10" id="chn-JO-eYr"/> - <constraint firstAttribute="bottom" secondItem="Wz7-gw-foA" secondAttribute="bottom" constant="10" id="e8b-hy-WHK"/> - <constraint firstAttribute="trailing" secondItem="YRy-AS-CMk" secondAttribute="trailing" constant="10" id="uaN-5Y-k6V"/> - <constraint firstItem="hVn-Fn-7td" firstAttribute="top" secondItem="sG1-7f-3rF" secondAttribute="top" constant="10" id="yLz-68-e22"/> - </constraints> - </view> </subviews> <viewLayoutGuide key="safeArea" id="USa-eR-a1s"/> <constraints> - <constraint firstItem="sG1-7f-3rF" firstAttribute="top" secondItem="vOO-VC-ekK" secondAttribute="top" id="0Wu-9f-jFf"/> <constraint firstItem="X49-xg-JXO" firstAttribute="trailing" secondItem="USa-eR-a1s" secondAttribute="trailing" id="5we-Fh-GVu"/> + <constraint firstItem="X49-xg-JXO" firstAttribute="top" secondItem="USa-eR-a1s" secondAttribute="top" id="E1U-4Q-6uu"/> <constraint firstItem="USa-eR-a1s" firstAttribute="bottom" secondItem="X49-xg-JXO" secondAttribute="bottom" id="aHq-g4-dUG"/> - <constraint firstItem="X49-xg-JXO" firstAttribute="top" secondItem="sG1-7f-3rF" secondAttribute="bottom" id="eeu-9y-t1U"/> - <constraint firstItem="sG1-7f-3rF" firstAttribute="trailing" secondItem="vOO-VC-ekK" secondAttribute="trailing" id="htz-S1-01v"/> - <constraint firstItem="sG1-7f-3rF" firstAttribute="leading" secondItem="vOO-VC-ekK" secondAttribute="leading" id="lLm-NY-aXQ"/> <constraint firstItem="X49-xg-JXO" firstAttribute="leading" secondItem="USa-eR-a1s" secondAttribute="leading" id="pfF-ag-f7x"/> </constraints> </view> <connections> - <outlet property="commentView" destination="sG1-7f-3rF" id="Nip-au-Ilu"/> - <outlet property="imageItem" destination="hVn-Fn-7td" id="tqx-nV-WfA"/> - <outlet property="labelUser" destination="YRy-AS-CMk" id="ijz-je-fBV"/> - <outlet property="newCommentField" destination="Wz7-gw-foA" id="PDr-8b-iQY"/> <outlet property="tableView" destination="X49-xg-JXO" id="GUb-8b-mIS"/> - <outlet property="viewContainerConstraint" destination="0Wu-9f-jFf" id="TGF-fh-T7Y"/> + <outlet property="viewContainerConstraint" destination="E1U-4Q-6uu" id="NpJ-Iz-DtL"/> </connections> </viewController> <placeholder placeholderIdentifier="IBFirstResponder" id="UOE-pW-DRy" userLabel="First Responder" sceneMemberID="firstResponder"/> diff --git a/iOSClient/Activity/NCActivity.swift b/iOSClient/Activity/NCActivity.swift index ab6354cfd..72e13a7c1 100644 --- a/iOSClient/Activity/NCActivity.swift +++ b/iOSClient/Activity/NCActivity.swift @@ -26,14 +26,12 @@ import UIKit import SwiftRichString import NCCommunication -class NCActivity: UIViewController { +class NCActivity: UIViewController, NCSharePagingContent { @IBOutlet weak var tableView: UITableView! - @IBOutlet weak var commentView: UIView! - @IBOutlet weak var imageItem: UIImageView! - @IBOutlet weak var labelUser: UILabel! - @IBOutlet weak var newCommentField: UITextField! + var commentView: NCActivityCommentView? + var textField: UITextField? { commentView?.newCommentField } @IBOutlet weak var viewContainerConstraint: NSLayoutConstraint! var height: CGFloat = 0 @@ -76,46 +74,34 @@ class NCActivity: UIViewController { if showComments { setupComments() - } else { - commentView.isHidden = true } } func setupComments() { - tableView.register(UINib(nibName: "NCShareCommentsCell", bundle: nil), forCellReuseIdentifier: "cell") - - newCommentField.placeholder = NSLocalizedString("_new_comment_", comment: "") - viewContainerConstraint.constant = height - // Display Name & Quota guard let activeAccount = NCManageDatabase.shared.getActiveAccount(), height > 0 else { - commentView.isHidden = true return } - let fileName = appDelegate.userBaseUrl + "-" + appDelegate.user + ".png" - let fileNameLocalPath = String(CCUtility.getDirectoryUserData()) + "/" + fileName - if let image = UIImage(contentsOfFile: fileNameLocalPath) { - imageItem.image = image - } else { - imageItem.image = UIImage(named: "avatar") - } - - if activeAccount.displayName.isEmpty { - labelUser.text = activeAccount.user - } else { - labelUser.text = activeAccount.displayName + tableView.register(UINib(nibName: "NCShareCommentsCell", bundle: nil), forCellReuseIdentifier: "cell") + commentView = Bundle.main.loadNibNamed("NCActivityCommentView", owner: self, options: nil)?.first as? NCActivityCommentView + commentView?.setup(urlBase: appDelegate, account: activeAccount) { newComment in + guard let newComment = newComment, !newComment.isEmpty, let metadata = self.metadata else { return } + NCCommunication.shared.putComments(fileId: metadata.fileId, message: newComment) { _, errorCode, errorDescription in + if errorCode == 0 { + self.commentView?.newCommentField.text?.removeAll() + self.loadComments() + } else { + NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode) + } + } } - labelUser.textColor = NCBrandColor.shared.label } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - appDelegate.activeViewController = self - NotificationCenter.default.addObserver(self, selector: #selector(initialize), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterInitialize), object: nil) - initialize() } @@ -127,6 +113,10 @@ class NCActivity: UIViewController { override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() tableView.tableFooterView = makeTableFooterView() + tableView.tableHeaderView = commentView + commentView?.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true + commentView?.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true + viewContainerConstraint.constant = height } // MARK: - NotificationCenter @@ -140,23 +130,6 @@ class NCActivity: UIViewController { tableView.reloadData() } - @IBAction func newCommentFieldDidEndOnExit(textField: UITextField) { - guard - let message = textField.text, - !message.isEmpty, - let metadata = self.metadata - else { return } - - NCCommunication.shared.putComments(fileId: metadata.fileId, message: message) { _, errorCode, errorDescription in - if errorCode == 0 { - self.newCommentField.text = "" - self.loadComments() - } else { - NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode) - } - } - } - func makeTableFooterView() -> UIView { let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: 100)) view.backgroundColor = .clear diff --git a/iOSClient/Activity/NCActivityCommentView.swift b/iOSClient/Activity/NCActivityCommentView.swift new file mode 100644 index 000000000..b3b0d9c4f --- /dev/null +++ b/iOSClient/Activity/NCActivityCommentView.swift @@ -0,0 +1,59 @@ +// +// NCActivityCommentView.swift +// Nextcloud +// +// Created by Henrik Storch on 04.01.22. +// Copyright © 2021 Henrik Storch. All rights reserved. +// +// Author Henrik Storch <henrik.storch@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 UIKit + +class NCActivityCommentView: UIView, UITextFieldDelegate { + @IBOutlet weak var imageItem: UIImageView! + @IBOutlet weak var labelUser: UILabel! + @IBOutlet weak var newCommentField: UITextField! + + var completionHandler: ((String?) -> Void)? + + func setup(urlBase: NCUserBaseUrl, account: tableAccount, completionHandler: @escaping (String?) -> Void) { + self.completionHandler = completionHandler + newCommentField.placeholder = NSLocalizedString("_new_comment_", comment: "") + newCommentField.delegate = self + + let fileName = urlBase.userBaseUrl + "-" + urlBase.user + ".png" + let fileNameLocalPath = String(CCUtility.getDirectoryUserData()) + "/" + fileName + if let image = UIImage(contentsOfFile: fileNameLocalPath) { + imageItem.image = image + } else { + imageItem.image = UIImage(named: "avatar") + } + + if account.displayName.isEmpty { + labelUser.text = account.user + } else { + labelUser.text = account.displayName + } + labelUser.textColor = NCBrandColor.shared.label + } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + textField.resignFirstResponder() + completionHandler?(textField.text) + return true + } +} diff --git a/iOSClient/Activity/NCActivityCommentView.xib b/iOSClient/Activity/NCActivityCommentView.xib new file mode 100644 index 000000000..0eba994ad --- /dev/null +++ b/iOSClient/Activity/NCActivityCommentView.xib @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> + <device id="retina6_1" orientation="portrait" appearance="light"/> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/> + <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <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 contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GuF-Pi-nHv" customClass="NCActivityCommentView" customModule="Nextcloud" customModuleProvider="target"> + <rect key="frame" x="0.0" y="0.0" width="269" height="100"/> + <subviews> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="YXy-gE-g7y"> + <rect key="frame" x="10" y="10" width="40" height="40"/> + <constraints> + <constraint firstAttribute="width" constant="40" id="kUz-t2-bFL"/> + <constraint firstAttribute="height" constant="40" id="yRS-7c-bMw"/> + </constraints> + </imageView> + <textField opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" clearButtonMode="always" translatesAutoresizingMaskIntoConstraints="NO" id="5pv-VB-vbL"> + <rect key="frame" x="60" y="60" width="199" height="30"/> + <constraints> + <constraint firstAttribute="height" constant="30" id="OLX-lD-EIH"/> + </constraints> + <fontDescription key="fontDescription" type="system" pointSize="14"/> + <textInputTraits key="textInputTraits"/> + </textField> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="user" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0Ja-ik-S0n"> + <rect key="frame" x="60" y="21.5" width="199" height="17"/> + <fontDescription key="fontDescription" type="system" pointSize="14"/> + <color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <nil key="highlightedColor"/> + </label> + </subviews> + <viewLayoutGuide key="safeArea" id="Y5x-Vi-PYA"/> + <constraints> + <constraint firstItem="YXy-gE-g7y" firstAttribute="top" secondItem="GuF-Pi-nHv" secondAttribute="top" constant="10" id="26g-rF-Ags"/> + <constraint firstAttribute="trailing" secondItem="0Ja-ik-S0n" secondAttribute="trailing" constant="10" id="7ue-4o-ZT2"/> + <constraint firstAttribute="height" constant="100" id="IsL-V9-dXU"/> + <constraint firstItem="0Ja-ik-S0n" firstAttribute="centerY" secondItem="YXy-gE-g7y" secondAttribute="centerY" id="NxM-vu-j06"/> + <constraint firstItem="5pv-VB-vbL" firstAttribute="leading" secondItem="YXy-gE-g7y" secondAttribute="trailing" constant="10" id="Oza-Za-mDZ"/> + <constraint firstItem="5pv-VB-vbL" firstAttribute="top" secondItem="YXy-gE-g7y" secondAttribute="bottom" constant="10" id="iie-Nv-YUr"/> + <constraint firstItem="0Ja-ik-S0n" firstAttribute="leading" secondItem="YXy-gE-g7y" secondAttribute="trailing" constant="10" id="j0L-NP-Z4H"/> + <constraint firstAttribute="trailing" secondItem="5pv-VB-vbL" secondAttribute="trailing" constant="10" id="oXJ-ov-XCK"/> + <constraint firstItem="YXy-gE-g7y" firstAttribute="leading" secondItem="GuF-Pi-nHv" secondAttribute="leading" constant="10" id="t5p-fd-swt"/> + <constraint firstAttribute="bottom" secondItem="5pv-VB-vbL" secondAttribute="bottom" constant="10" id="yEr-QL-mtD"/> + </constraints> + <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> + <connections> + <outlet property="imageItem" destination="YXy-gE-g7y" id="yWc-3P-gIU"/> + <outlet property="labelUser" destination="0Ja-ik-S0n" id="GkS-TV-2ic"/> + <outlet property="newCommentField" destination="5pv-VB-vbL" id="8vL-Mt-0rZ"/> + </connections> + <point key="canvasLocation" x="-231.15942028985509" y="-99.776785714285708"/> + </view> + </objects> +</document> diff --git a/iOSClient/Brand/NCBrand.swift b/iOSClient/Brand/NCBrand.swift index 92c2b987c..cc01ffecd 100755 --- a/iOSClient/Brand/NCBrand.swift +++ b/iOSClient/Brand/NCBrand.swift @@ -215,6 +215,16 @@ class NCBrandColor: NSObject { } } + @objc public var secondaryLabel: UIColor { + get { + if #available(iOS 13, *) { + return .secondaryLabel + } else { + return UIColor(red: 0.24, green: 0.24, blue: 0.26, alpha: 0.6) + } + } + } + @objc public var separator: UIColor { get { if #available(iOS 13, *) { diff --git a/iOSClient/Extensions/DateFormatter+Extension.swift b/iOSClient/Extensions/DateFormatter+Extension.swift new file mode 100644 index 000000000..aa126ce78 --- /dev/null +++ b/iOSClient/Extensions/DateFormatter+Extension.swift @@ -0,0 +1,33 @@ +// +// DateFormatter+Extension.swift +// Nextcloud +// +// Created by Henrik Storch on 18.03.22. +// Copyright © 2022 Henrik Storch. All rights reserved. +// +// Author Henrik Storch <henrik.storch@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 + +extension DateFormatter { + static let shareExpDate: DateFormatter = { + let dateFormatter = DateFormatter() + dateFormatter.formatterBehavior = .behavior10_4 + dateFormatter.dateStyle = .medium + return dateFormatter + }() +} diff --git a/iOSClient/Extensions/String+Extensions.swift b/iOSClient/Extensions/String+Extensions.swift index 75e9d068a..f30751ed7 100644 --- a/iOSClient/Extensions/String+Extensions.swift +++ b/iOSClient/Extensions/String+Extensions.swift @@ -54,7 +54,7 @@ extension String { //https://stackoverflow.com/a/32166735/9506784 let length = Int(CC_MD5_DIGEST_LENGTH) - let messageData = self.data(using: .utf8)! + let messageData = self.data(using: .utf8) ?? Data() var digestData = Data(count: length) _ = digestData.withUnsafeMutableBytes { digestBytes -> UInt8 in diff --git a/iOSClient/Extensions/UIAlertController+Extension.swift b/iOSClient/Extensions/UIAlertController+Extension.swift index 1e8cf2a0f..90a55c09d 100644 --- a/iOSClient/Extensions/UIAlertController+Extension.swift +++ b/iOSClient/Extensions/UIAlertController+Extension.swift @@ -66,4 +66,26 @@ extension UIAlertController { alertController.addAction(okAction) return alertController } + + static func withTextField(titleKey: String, textFieldConfiguration: ((UITextField) -> Void)?, completion: @escaping (String?) -> Void) -> UIAlertController { + let alertController = UIAlertController(title: NSLocalizedString(titleKey, comment: ""), message: "", preferredStyle: .alert) + alertController.addTextField { textField in + textFieldConfiguration?(textField) + } + alertController.addAction(UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .default) { _ in }) + let okAction = UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default) { _ in + completion(alertController.textFields?.first?.text) + } + + alertController.addAction(okAction) + return alertController + } + + static func password(titleKey: String, completion: @escaping (String?) -> Void) -> UIAlertController { + return .withTextField(titleKey: titleKey, textFieldConfiguration: { textField in + textField.isSecureTextEntry = true + textField.placeholder = NSLocalizedString("_password_", comment: "") + }, completion: completion) + + } } diff --git a/iOSClient/Extensions/UIToolbar+Extension.swift b/iOSClient/Extensions/UIToolbar+Extension.swift new file mode 100644 index 000000000..983c4d7b3 --- /dev/null +++ b/iOSClient/Extensions/UIToolbar+Extension.swift @@ -0,0 +1,77 @@ +// +// UIToolbar+Extension.swift +// Nextcloud +// +// Created by Henrik Storch on 18.03.22. +// Copyright © 2022 Henrik Storch. All rights reserved. +// +// Author Henrik Storch <henrik.storch@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 UIKit + +extension UIToolbar { + static func toolbar(onClear: (() -> Void)?, completion: @escaping () -> Void) -> UIToolbar { + let toolbar = UIToolbar() + toolbar.sizeToFit() + var buttons: [UIBarButtonItem] = [] + + if let onClear = onClear { + let clearButton = UIBarButtonItem(title: NSLocalizedString("_clear_", comment: ""), style: .plain) { + onClear() + } + buttons.append(clearButton) + } + buttons.append(UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)) + let doneButton = UIBarButtonItem(title: NSLocalizedString("_done_", comment: ""), style: .done) { + completion() + } + buttons.append(doneButton) + toolbar.setItems(buttons, animated: false) + return toolbar + } + + // by default inputAccessoryView does not respect safeArea + var wrappedSafeAreaContainer: UIView { + let view = InputBarWrapper() + view.addSubview(self) + self.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + self.topAnchor.constraint(equalTo: view.topAnchor), + self.leftAnchor.constraint(equalTo: view.leftAnchor), + self.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), + self.rightAnchor.constraint(equalTo: view.rightAnchor) + ]) + return view + } +} + +// https://stackoverflow.com/a/67985180/9506784 +class InputBarWrapper: UIView { + + var desiredHeight: CGFloat = 0 { + didSet { invalidateIntrinsicContentSize() } + } + + override var intrinsicContentSize: CGSize { CGSize(width: 0, height: desiredHeight) } + + required init?(coder aDecoder: NSCoder) { fatalError() } + + override init(frame: CGRect) { + super.init(frame: frame) + autoresizingMask = .flexibleHeight + } +} diff --git a/iOSClient/Images.xcassets/circle.fill.imageset/Contents.json b/iOSClient/Images.xcassets/circle_fill.imageset/Contents.json index b73baca81..b73baca81 100644 --- a/iOSClient/Images.xcassets/circle.fill.imageset/Contents.json +++ b/iOSClient/Images.xcassets/circle_fill.imageset/Contents.json diff --git a/iOSClient/Images.xcassets/circle.fill.imageset/circle.pdf b/iOSClient/Images.xcassets/circle_fill.imageset/circle.pdf Binary files differindex 4be68b831..4be68b831 100644 --- a/iOSClient/Images.xcassets/circle.fill.imageset/circle.pdf +++ b/iOSClient/Images.xcassets/circle_fill.imageset/circle.pdf diff --git a/iOSClient/Images.xcassets/lock.open.imageset/Contents.json b/iOSClient/Images.xcassets/lock_open.imageset/Contents.json index d6fb0c7a0..d6fb0c7a0 100644 --- a/iOSClient/Images.xcassets/lock.open.imageset/Contents.json +++ b/iOSClient/Images.xcassets/lock_open.imageset/Contents.json diff --git a/iOSClient/Images.xcassets/lock.open.imageset/lock-open-variant-outline.svg b/iOSClient/Images.xcassets/lock_open.imageset/lock-open-variant-outline.svg index d1e4c56ff..d1e4c56ff 100644 --- a/iOSClient/Images.xcassets/lock.open.imageset/lock-open-variant-outline.svg +++ b/iOSClient/Images.xcassets/lock_open.imageset/lock-open-variant-outline.svg diff --git a/iOSClient/Menu/NCShare+Menu.swift b/iOSClient/Menu/NCShare+Menu.swift new file mode 100644 index 000000000..88defd5b1 --- /dev/null +++ b/iOSClient/Menu/NCShare+Menu.swift @@ -0,0 +1,121 @@ +// +// NCShare+Menu.swift +// Nextcloud +// +// Created by Henrik Storch on 16.03.22. +// Copyright © 2022 Henrik Storch. All rights reserved. +// +// Author Henrik Storch <henrik.storch@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 + +extension NCShare { + func toggleShareMenu(for share: tableShare) { + + var actions = [NCMenuAction]() + + if share.shareType == 3, canReshare { + actions.append( + NCMenuAction( + title: NSLocalizedString("_share_add_sharelink_", comment: ""), + icon: NCUtility.shared.loadImage(named: "shareAdd"), + action: { _ in + self.makeNewLinkShare() + } + ) + ) + } + + actions.append( + NCMenuAction( + title: NSLocalizedString("_details_", comment: ""), + icon: NCUtility.shared.loadImage(named: "edit"), + action: { _ in + guard + let advancePermission = UIStoryboard(name: "NCShare", bundle: nil).instantiateViewController(withIdentifier: "NCShareAdvancePermission") as? NCShareAdvancePermission, + let navigationController = self.navigationController, !share.isInvalidated else { return } + advancePermission.networking = self.networking + advancePermission.share = tableShare(value: share) + advancePermission.oldTableShare = tableShare(value: share) + advancePermission.metadata = self.metadata + navigationController.pushViewController(advancePermission, animated: true) + } + ) + ) + + actions.append( + NCMenuAction( + title: NSLocalizedString("_share_unshare_", comment: ""), + icon: NCUtility.shared.loadImage(named: "trash"), + action: { _ in + self.networking?.unShare(idShare: share.idShare) + } + ) + ) + + self.presentMenu(with: actions) + } + + func toggleUserPermissionMenu(isDirectory: Bool, tableShare: tableShare) { + var actions = [NCMenuAction]() + + actions.append( + NCMenuAction( + title: NSLocalizedString("_share_read_only_", comment: ""), + icon: UIImage(), + selected: tableShare.permissions == (NCGlobal.shared.permissionReadShare + NCGlobal.shared.permissionShareShare) || tableShare.permissions == NCGlobal.shared.permissionReadShare, + on: false, + action: { _ in + let canShare = CCUtility.isPermission(toCanShare: tableShare.permissions) + let permissions = CCUtility.getPermissionsValue(byCanEdit: false, andCanCreate: false, andCanChange: false, andCanDelete: false, andCanShare: canShare, andIsFolder: isDirectory) + self.updateSharePermissions(share: tableShare, permissions: permissions) + } + ) + ) + + actions.append( + NCMenuAction( + title: isDirectory ? NSLocalizedString("_share_allow_upload_", comment: "") : NSLocalizedString("_share_editing_", comment: ""), + icon: UIImage(), + selected: hasUploadPermission(tableShare: tableShare), + on: false, + action: { _ in + let canShare = CCUtility.isPermission(toCanShare: tableShare.permissions) + let permissions = CCUtility.getPermissionsValue(byCanEdit: true, andCanCreate: true, andCanChange: true, andCanDelete: true, andCanShare: canShare, andIsFolder: isDirectory) + self.updateSharePermissions(share: tableShare, permissions: permissions) + } + ) + ) + + self.presentMenu(with: actions) + } + + fileprivate func hasUploadPermission(tableShare: tableShare) -> Bool { + let uploadPermissions = [ + NCGlobal.shared.permissionMaxFileShare, + NCGlobal.shared.permissionMaxFolderShare, + NCGlobal.shared.permissionDefaultFileRemoteShareNoSupportShareOption, + NCGlobal.shared.permissionDefaultFolderRemoteShareNoSupportShareOption] + return uploadPermissions.contains(tableShare.permissions) + } + + func updateSharePermissions(share: tableShare, permissions: Int) { + let updatedShare = tableShare(value: share) + updatedShare.permissions = permissions + networking?.updateShare(option: updatedShare) + } +} diff --git a/iOSClient/NCGlobal.swift b/iOSClient/NCGlobal.swift index 8eea92a2e..a943207e1 100644 --- a/iOSClient/NCGlobal.swift +++ b/iOSClient/NCGlobal.swift @@ -350,8 +350,6 @@ class NCGlobal: NSObject { let notificationCenterChangedLocation = "changedLocation" let notificationStatusAuthorizationChangedLocation = "statusAuthorizationChangedLocation" - let notificationCenterShareChangePermissions = "shareChangePermissions" // userInfo: idShare, permissions, hideDownload - let notificationCenterDownloadedThumbnail = "DownloadedThumbnail" // userInfo: ocId let notificationCenterHidePlayerToolBar = "hidePlayerToolBar" // userInfo: ocId diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermission.swift b/iOSClient/Share/Advanced/NCShareAdvancePermission.swift new file mode 100644 index 000000000..2e0da22c0 --- /dev/null +++ b/iOSClient/Share/Advanced/NCShareAdvancePermission.swift @@ -0,0 +1,192 @@ +// +// NCShareAdvancePermission.swift +// Nextcloud +// +// Created by T-systems on 09/08/21. +// Copyright © 2022 Henrik Storch. All rights reserved. +// +// Author Henrik Storch <henrik.storch@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 UIKit +import NCCommunication +import SVGKit +import CloudKit + +class NCShareAdvancePermission: UITableViewController, NCShareAdvanceFotterDelegate, NCShareDetail { + func dismissShareAdvanceView(shouldSave: Bool) { + guard shouldSave else { + guard oldTableShare?.hasChanges(comparedTo: share) != false else { + navigationController?.popViewController(animated: true) + return + } + let alert = UIAlertController( + title: NSLocalizedString("_cancel_request_", comment: ""), + message: NSLocalizedString("_discard_changes_info_", comment: ""), + preferredStyle: .alert) + alert.addAction(UIAlertAction( + title: NSLocalizedString("_discard_changes_", comment: ""), + style: .destructive, + handler: { _ in self.navigationController?.popViewController(animated: true) })) + alert.addAction(UIAlertAction(title: NSLocalizedString("_continue_editing_", comment: ""), style: .default)) + self.present(alert, animated: true) + return + } + if isNewShare { + networking?.createShare(option: share) + } else { + networking?.updateShare(option: share) + } + navigationController?.popViewController(animated: true) + } + + var oldTableShare: tableShare? + var share: NCTableShareable! + var isNewShare: Bool { share is NCTableShareOptions } + var metadata: tableMetadata! + var shareConfig: NCShareConfig! + var networking: NCShareNetworking? + + override func viewDidLoad() { + super.viewDidLoad() + self.shareConfig = NCShareConfig(parentMetadata: metadata, share: share) + + tableView.estimatedRowHeight = tableView.rowHeight + tableView.rowHeight = UITableView.automaticDimension + self.setNavigationTitle() + self.navigationItem.hidesBackButton = true + if #available(iOS 13.0, *) { + // disbale pull to dimiss + isModalInPresentation = true + } + } + + override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + guard tableView.tableHeaderView == nil, tableView.tableFooterView == nil else { return } + setupHeaderView() + setupFooterView() + } + + func setupFooterView() { + guard let footerView = (Bundle.main.loadNibNamed("NCShareAdvancePermissionFooter", owner: self, options: nil)?.first as? NCShareAdvancePermissionFooter) else { return } + footerView.setupUI(delegate: self) + + // tableFooterView can't use auto layout directly + let container = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 120)) + container.addSubview(footerView) + tableView.tableFooterView = container + footerView.translatesAutoresizingMaskIntoConstraints = false + footerView.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true + footerView.heightAnchor.constraint(equalTo: container.heightAnchor).isActive = true + footerView.widthAnchor.constraint(equalTo: container.widthAnchor).isActive = true + } + + func setupHeaderView() { + guard let headerView = (Bundle.main.loadNibNamed("NCShareAdvancePermissionHeader", owner: self, options: nil)?.first as? NCShareAdvancePermissionHeader) else { return } + headerView.setupUI(with: metadata) + + let container = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 220)) + container.addSubview(headerView) + tableView.tableHeaderView = container + headerView.translatesAutoresizingMaskIntoConstraints = false + headerView.topAnchor.constraint(equalTo: container.topAnchor).isActive = true + headerView.heightAnchor.constraint(equalTo: container.heightAnchor).isActive = true + headerView.widthAnchor.constraint(equalTo: container.widthAnchor).isActive = true + } + + override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + if section == 0 { + return NSLocalizedString("_permissions_", comment: "") + } else if section == 1 { + return NSLocalizedString("_advanced_", comment: "") + } else { return nil } + } + + override func numberOfSections(in tableView: UITableView) -> Int { + return 2 + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if section == 0 { + // check reshare permission, if restricted add note + let maxPermission = metadata.directory ? NCGlobal.shared.permissionMaxFolderShare : NCGlobal.shared.permissionMaxFileShare + return shareConfig.resharePermission != maxPermission ? shareConfig.permissions.count + 1 : shareConfig.permissions.count + } else if section == 1 { + return shareConfig.advanced.count + } else { return 0 } + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = shareConfig.cellFor(indexPath: indexPath) else { + let noteCell = UITableViewCell(style: .subtitle, reuseIdentifier: "noteCell") + noteCell.detailTextLabel?.text = NSLocalizedString("_share_reshare_restricted_", comment: "") + noteCell.detailTextLabel?.isEnabled = false + noteCell.isUserInteractionEnabled = false + noteCell.detailTextLabel?.numberOfLines = 0 + return noteCell + } + if let cell = cell as? NCShareDateCell { cell.onReload = tableView.reloadData } + return cell + } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + tableView.deselectRow(at: indexPath, animated: true) + guard let cellConfig = shareConfig.config(for: indexPath) else { return } + guard let cellConfig = cellConfig as? NCShareDetails else { + cellConfig.didSelect(for: share) + tableView.reloadData() + return + } + + switch cellConfig { + case .hideDownload: + share.hideDownload.toggle() + tableView.reloadData() + case .expirationDate: + let cell = tableView.cellForRow(at: indexPath) as? NCShareDateCell + cell?.textField.becomeFirstResponder() + case .password: + guard share.password.isEmpty else { + share.password = "" + tableView.reloadData() + return + } + let alertController = UIAlertController.password(titleKey: "_share_password_") { password in + self.share.password = password ?? "" + tableView.reloadData() + } + self.present(alertController, animated: true) + case .note: + let storyboard = UIStoryboard(name: "NCShare", bundle: nil) + guard let viewNewUserComment = storyboard.instantiateViewController(withIdentifier: "NCShareNewUserAddComment") as? NCShareNewUserAddComment else { return } + viewNewUserComment.metadata = self.metadata + viewNewUserComment.share = self.share + viewNewUserComment.onDismiss = tableView.reloadData + self.navigationController?.pushViewController(viewNewUserComment, animated: true) + case .label: + let alertController = UIAlertController.withTextField(titleKey: "_share_link_name_") { textField in + textField.placeholder = cellConfig.title + textField.text = self.share.label + } completion: { newValue in + self.share.label = newValue ?? "" + self.setNavigationTitle() + tableView.reloadData() + } + self.present(alertController, animated: true) + } + } +} diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.swift b/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.swift new file mode 100644 index 000000000..ffad1f97e --- /dev/null +++ b/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.swift @@ -0,0 +1,66 @@ +// +// NCShareAdvancePermissionFooter.swift +// Nextcloud +// +// Created by T-systems on 09/08/21. +// Copyright © 2022 Henrik Storch. All rights reserved. +// +// Author Henrik Storch <henrik.storch@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 UIKit + +protocol NCShareAdvanceFotterDelegate: AnyObject { + var isNewShare: Bool { get } + func dismissShareAdvanceView(shouldSave: Bool) +} + +class NCShareAdvancePermissionFooter: UIView { + @IBOutlet weak var buttonCancel: UIButton! + @IBOutlet weak var buttonNext: UIButton! + weak var delegate: NCShareAdvanceFotterDelegate? + + func setupUI(delegate: NCShareAdvanceFotterDelegate?) { + self.delegate = delegate + backgroundColor = .clear + + buttonCancel.backgroundColor = .clear + buttonCancel.addTarget(self, action: #selector(cancelClicked), for: .touchUpInside) + buttonCancel.setTitle(NSLocalizedString("_cancel_", comment: ""), for: .normal) + + buttonCancel.layer.cornerRadius = 25 + buttonCancel.layer.masksToBounds = true + buttonCancel.layer.borderWidth = 1 + buttonCancel.backgroundColor = NCBrandColor.shared.secondarySystemBackground + buttonCancel.layer.borderColor = NCBrandColor.shared.systemGray.cgColor + buttonCancel.setTitleColor(NCBrandColor.shared.label.withAlphaComponent(0.3), for: .highlighted) + + buttonNext.setTitle(NSLocalizedString(delegate?.isNewShare == true ? "_share_" : "_save_", comment: ""), for: .normal) + buttonNext.layer.cornerRadius = 25 + buttonNext.layer.masksToBounds = true + buttonNext.backgroundColor = NCBrandColor.shared.brand + buttonNext.addTarget(self, action: #selector(nextClicked), for: .touchUpInside) + buttonNext.setTitleColor(UIColor(white: 1, alpha: 0.3), for: .highlighted) + } + + @objc func cancelClicked() { + delegate?.dismissShareAdvanceView(shouldSave: false) + } + + @objc func nextClicked() { + delegate?.dismissShareAdvanceView(shouldSave: true) + } +} diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.xib b/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.xib new file mode 100644 index 000000000..40b515e7d --- /dev/null +++ b/iOSClient/Share/Advanced/NCShareAdvancePermissionFooter.xib @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> + <device id="retina6_1" orientation="portrait" appearance="light"/> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/> + <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <capability name="System colors in document resources" minToolsVersion="11.0"/> + <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 contentMode="scaleToFill" id="iN0-l3-epB" customClass="NCShareAdvancePermissionFooter" customModule="Nextcloud" customModuleProvider="target"> + <rect key="frame" x="0.0" y="0.0" width="688" height="376"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rCI-63-PtL"> + <rect key="frame" x="16" y="168" width="320" height="50"/> + <constraints> + <constraint firstAttribute="height" constant="50" id="vdI-sH-cTb"/> + </constraints> + <fontDescription key="fontDescription" type="system" pointSize="18"/> + <color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/> + <state key="normal" title="Cancel"> + <color key="titleColor" systemColor="labelColor"/> + </state> + </button> + <button opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Mg2-Ou-yoX"> + <rect key="frame" x="352" y="168" width="320" height="50"/> + <color key="backgroundColor" systemColor="systemBlueColor"/> + <fontDescription key="fontDescription" type="system" pointSize="18"/> + <state key="normal" title="Send share"> + <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </state> + </button> + </subviews> + <viewLayoutGuide key="safeArea" id="sWQ-1v-CIt"/> + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstItem="Mg2-Ou-yoX" firstAttribute="leading" secondItem="rCI-63-PtL" secondAttribute="trailing" constant="16" id="4Px-cS-Hta"/> + <constraint firstItem="sWQ-1v-CIt" firstAttribute="trailing" secondItem="Mg2-Ou-yoX" secondAttribute="trailing" constant="16" id="Jdi-WJ-zVF"/> + <constraint firstItem="sWQ-1v-CIt" firstAttribute="centerY" secondItem="Mg2-Ou-yoX" secondAttribute="centerY" id="SzT-aI-aUz"/> + <constraint firstItem="Mg2-Ou-yoX" firstAttribute="height" secondItem="rCI-63-PtL" secondAttribute="height" id="bNp-Nf-uMw"/> + <constraint firstItem="Mg2-Ou-yoX" firstAttribute="width" secondItem="rCI-63-PtL" secondAttribute="width" id="dfu-GZ-P99"/> + <constraint firstItem="rCI-63-PtL" firstAttribute="centerY" secondItem="Mg2-Ou-yoX" secondAttribute="centerY" id="hEl-ij-sMX"/> + <constraint firstItem="rCI-63-PtL" firstAttribute="leading" secondItem="sWQ-1v-CIt" secondAttribute="leading" constant="16" id="s9t-ud-ofw"/> + </constraints> + <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> + <connections> + <outlet property="buttonCancel" destination="rCI-63-PtL" id="SoT-Ko-LL5"/> + <outlet property="buttonNext" destination="Mg2-Ou-yoX" id="F2d-L5-dHo"/> + </connections> + <point key="canvasLocation" x="139.13043478260872" y="43.526785714285715"/> + </view> + </objects> + <resources> + <systemColor name="labelColor"> + <color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </systemColor> + <systemColor name="systemBlueColor"> + <color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + </systemColor> + </resources> +</document> diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.swift b/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.swift new file mode 100644 index 000000000..8ff5828b7 --- /dev/null +++ b/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.swift @@ -0,0 +1,51 @@ +// +// NCShareAdvancePermissionHeader.swift +// Nextcloud +// +// Created by T-systems on 10/08/21. +// Copyright © 2022 Henrik Storch. All rights reserved. +// +// Author Henrik Storch <henrik.storch@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 UIKit + +class NCShareAdvancePermissionHeader: UIView { + @IBOutlet weak var imageView: UIImageView! + @IBOutlet weak var fileName: UILabel! + @IBOutlet weak var info: UILabel! + @IBOutlet weak var fullWidthImageView: UIImageView! + + func setupUI(with metadata: tableMetadata) { + if FileManager.default.fileExists(atPath: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) { + fullWidthImageView.image = NCUtility.shared.getImageMetadata(metadata, for: frame.height) + fullWidthImageView.contentMode = .scaleAspectFill + imageView.isHidden = true + } else { + if metadata.directory { + imageView.image = NCBrandColor.cacheImages.folder + } else if !metadata.iconName.isEmpty { + imageView.image = UIImage(named: metadata.iconName) + } else { + imageView.image = NCBrandColor.cacheImages.file + } + } + fileName.text = metadata.fileNameView + fileName.textColor = NCBrandColor.shared.label + info.textColor = NCBrandColor.shared.secondaryLabel + info.text = CCUtility.transformedSize(metadata.size) + ", " + CCUtility.dateDiff(metadata.date as Date) + } +} diff --git a/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.xib b/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.xib new file mode 100644 index 000000000..beb60d8c5 --- /dev/null +++ b/iOSClient/Share/Advanced/NCShareAdvancePermissionHeader.xib @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> + <device id="retina4_7" orientation="portrait" appearance="light"/> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/> + <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <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 contentMode="scaleToFill" id="wbW-yR-MZC" customClass="NCShareAdvancePermissionHeader" customModule="Nextcloud" customModuleProvider="target"> + <rect key="frame" x="0.0" y="0.0" width="414" height="210"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="cki-Ql-o1I"> + <rect key="frame" x="0.0" y="0.0" width="414" height="150"/> + <constraints> + <constraint firstAttribute="height" constant="150" id="9GH-KF-f8P"/> + </constraints> + </imageView> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Dkw-QP-be6"> + <rect key="frame" x="16" y="27" width="96" height="96"/> + <constraints> + <constraint firstAttribute="height" constant="96" id="TW7-8v-NRJ"/> + <constraint firstAttribute="width" constant="96" id="Vbz-xZ-L5k"/> + </constraints> + </imageView> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pu4-Nd-M08"> + <rect key="frame" x="16" y="166" width="382" height="18"/> + <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="15"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VaC-Fz-kHk"> + <rect key="frame" x="16" y="188" width="383" height="16"/> + <fontDescription key="fontDescription" type="system" pointSize="13"/> + <color key="textColor" red="0.76862745099999996" green="0.77647058820000003" blue="0.77647058820000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <nil key="highlightedColor"/> + </label> + </subviews> + <viewLayoutGuide key="safeArea" id="KLE-vd-Dsn"/> + <constraints> + <constraint firstItem="pu4-Nd-M08" firstAttribute="leading" secondItem="KLE-vd-Dsn" secondAttribute="leading" constant="16" id="0Uy-ra-MtM"/> + <constraint firstItem="pu4-Nd-M08" firstAttribute="top" secondItem="cki-Ql-o1I" secondAttribute="bottom" constant="16" id="Cce-7Y-iw9"/> + <constraint firstAttribute="trailing" secondItem="VaC-Fz-kHk" secondAttribute="trailing" constant="15" id="Ebg-3T-03W"/> + <constraint firstItem="Dkw-QP-be6" firstAttribute="leading" secondItem="KLE-vd-Dsn" secondAttribute="leading" constant="16" id="KPc-al-RWN"/> + <constraint firstItem="KLE-vd-Dsn" firstAttribute="top" secondItem="cki-Ql-o1I" secondAttribute="top" id="KsC-jf-M6F"/> + <constraint firstAttribute="trailing" secondItem="cki-Ql-o1I" secondAttribute="trailing" id="Wdl-Rb-Pjy"/> + <constraint firstItem="VaC-Fz-kHk" firstAttribute="leading" secondItem="pu4-Nd-M08" secondAttribute="leading" id="Ycb-wy-uL6"/> + <constraint firstItem="cki-Ql-o1I" firstAttribute="leading" secondItem="KLE-vd-Dsn" secondAttribute="leading" id="ZlH-LU-x2x"/> + <constraint firstItem="KLE-vd-Dsn" firstAttribute="trailing" secondItem="pu4-Nd-M08" secondAttribute="trailing" constant="16" id="bO0-yQ-OWX"/> + <constraint firstItem="Dkw-QP-be6" firstAttribute="centerY" secondItem="cki-Ql-o1I" secondAttribute="centerY" id="dME-jJ-PwO"/> + <constraint firstItem="VaC-Fz-kHk" firstAttribute="top" secondItem="pu4-Nd-M08" secondAttribute="bottom" constant="4" id="zkb-Jm-sin"/> + </constraints> + <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> + <connections> + <outlet property="fileName" destination="pu4-Nd-M08" id="iLj-ya-6hM"/> + <outlet property="fullWidthImageView" destination="cki-Ql-o1I" id="KYn-3Y-SZH"/> + <outlet property="imageView" destination="Dkw-QP-be6" id="wzX-Sb-Ajt"/> + <outlet property="info" destination="VaC-Fz-kHk" id="n9O-6c-qsd"/> + </connections> + <point key="canvasLocation" x="35.625" y="27.5"/> + </view> + </objects> +</document> diff --git a/iOSClient/Share/Advanced/NCShareCells.swift b/iOSClient/Share/Advanced/NCShareCells.swift new file mode 100644 index 000000000..3b14d4555 --- /dev/null +++ b/iOSClient/Share/Advanced/NCShareCells.swift @@ -0,0 +1,300 @@ +// +// NCShareCells.swift +// Nextcloud +// +// Created by Henrik Storch on 18.03.22. +// Copyright © 2022 Henrik Storch. All rights reserved. +// +// Author Henrik Storch <henrik.storch@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 UIKit + +protocol NCShareCellConfig { + var title: String { get } + func getCell(for share: NCTableShareable) -> UITableViewCell + func didSelect(for share: NCTableShareable) +} + +protocol NCToggleCellConfig: NCShareCellConfig { + func isOn(for share: NCTableShareable) -> Bool + func didChange(_ share: NCTableShareable, to newValue: Bool) +} + +extension NCToggleCellConfig { + func getCell(for share: NCTableShareable) -> UITableViewCell { + return NCShareToggleCell(isOn: isOn(for: share)) + } + + func didSelect(for share: NCTableShareable) { + didChange(share, to: !isOn(for: share)) + } +} + +protocol NCPermission: NCToggleCellConfig { + static var forDirectory: [Self] { get } + static var forFile: [Self] { get } + func hasResharePermission(for parentPermission: Int) -> Bool +} + +enum NCUserPermission: CaseIterable, NCPermission { + func hasResharePermission(for parentPermission: Int) -> Bool { + return ((permissionBitFlag & parentPermission) != 0) + } + + var permissionBitFlag: Int { + switch self { + case .reshare: return NCGlobal.shared.permissionShareShare + case .edit: return NCGlobal.shared.permissionUpdateShare + case .create: return NCGlobal.shared.permissionCreateShare + case .delete: return NCGlobal.shared.permissionDeleteShare + } + } + + func didChange(_ share: NCTableShareable, to newValue: Bool) { + share.permissions ^= permissionBitFlag + } + + func isOn(for share: NCTableShareable) -> Bool { + return (share.permissions & permissionBitFlag) != 0 + } + + case reshare, edit, create, delete + static let forDirectory: [NCUserPermission] = NCUserPermission.allCases + static let forFile: [NCUserPermission] = [.reshare, .edit] + + var title: String { + switch self { + case .reshare: return NSLocalizedString("_share_can_reshare_", comment: "") + case .edit: return NSLocalizedString("_share_can_change_", comment: "") + case .create: return NSLocalizedString("_share_can_create_", comment: "") + case .delete: return NSLocalizedString("_share_can_delete_", comment: "") + } + } +} + +enum NCLinkPermission: NCPermission { + func didChange(_ share: NCTableShareable, to newValue: Bool) { + guard self != .allowEdit || newValue else { + share.permissions = NCGlobal.shared.permissionReadShare + return + } + share.permissions = permissionValue + } + + func hasResharePermission(for parentPermission: Int) -> Bool { + permissionValue & parentPermission == permissionValue + } + + var permissionValue: Int { + switch self { + case .allowEdit: + return CCUtility.getPermissionsValue( + byCanEdit: true, + andCanCreate: true, + andCanChange: true, + andCanDelete: true, + andCanShare: false, + andIsFolder: false) + case .viewOnly: + return CCUtility.getPermissionsValue( + byCanEdit: false, + andCanCreate: false, + andCanChange: false, + andCanDelete: false, + // not possible to create "read-only" shares without reshare option + // https://github.com/nextcloud/server/blame/f99876997a9119518fe5f7ad3a3a51d33459d4cc/apps/files_sharing/lib/Controller/ShareAPIController.php#L1104-L1107 + andCanShare: true, + andIsFolder: true) + case .uploadEdit: + return CCUtility.getPermissionsValue( + byCanEdit: true, + andCanCreate: true, + andCanChange: true, + andCanDelete: true, + andCanShare: false, + andIsFolder: true) + case .fileDrop: + return NCGlobal.shared.permissionCreateShare + } + } + + func isOn(for share: NCTableShareable) -> Bool { + switch self { + case .allowEdit: return CCUtility.isAnyPermission(toEdit: share.permissions) + case .viewOnly: return !CCUtility.isAnyPermission(toEdit: share.permissions) && share.permissions != NCGlobal.shared.permissionCreateShare + case .uploadEdit: return CCUtility.isAnyPermission(toEdit: share.permissions) && share.permissions != NCGlobal.shared.permissionCreateShare + case .fileDrop: return share.permissions == NCGlobal.shared.permissionCreateShare + } + } + + var title: String { + switch self { + case .allowEdit: return NSLocalizedString("_share_can_change_", comment: "") + case .viewOnly: return NSLocalizedString("_share_read_only_", comment: "") + case .uploadEdit: return NSLocalizedString("_share_allow_upload_", comment: "") + case .fileDrop: return NSLocalizedString("_share_file_drop_", comment: "") + } + } + + case allowEdit, viewOnly, uploadEdit, fileDrop + static let forDirectory: [NCLinkPermission] = [.viewOnly, .uploadEdit, .fileDrop] + static let forFile: [NCLinkPermission] = [.allowEdit] +} + +enum NCShareDetails: CaseIterable, NCShareCellConfig { + func didSelect(for share: NCTableShareable) { + switch self { + case .hideDownload: share.hideDownload.toggle() + case .expirationDate: return + case .password: return + case .note: return + case .label: return + } + } + + func getCell(for share: NCTableShareable) -> UITableViewCell { + switch self { + case .hideDownload: + return NCShareToggleCell(isOn: share.hideDownload) + case .expirationDate: + return NCShareDateCell(share: share) + case .password: return NCShareToggleCell(isOn: !share.password.isEmpty, customIcons: ("lock", "lock_open")) + case .note: + let cell = UITableViewCell(style: .value1, reuseIdentifier: "shareNote") + cell.detailTextLabel?.text = share.note + cell.accessoryType = .disclosureIndicator + return cell + case .label: + let cell = UITableViewCell(style: .value1, reuseIdentifier: "shareLabel") + cell.detailTextLabel?.text = share.label + return cell + } + } + + var title: String { + switch self { + case .hideDownload: return NSLocalizedString("_share_hide_download_", comment: "") + case .expirationDate: return NSLocalizedString("_share_expiration_date_", comment: "") + case .password: return NSLocalizedString("_share_password_protect_", comment: "") + case .note: return NSLocalizedString("_share_note_recipient_", comment: "") + case .label: return NSLocalizedString("_share_link_name_", comment: "") + } + } + + case label, hideDownload, expirationDate, password, note + static let forLink: [NCShareDetails] = NCShareDetails.allCases + static let forUser: [NCShareDetails] = [.expirationDate, .note] +} + +struct NCShareConfig { + let permissions: [NCPermission] + let advanced: [NCShareDetails] + let share: NCTableShareable + let resharePermission: Int + + init(parentMetadata: tableMetadata, share: NCTableShareable) { + self.share = share + self.resharePermission = parentMetadata.sharePermissionsCollaborationServices + let type: NCPermission.Type = share.shareType == NCShareCommon.shared.SHARE_TYPE_LINK ? NCLinkPermission.self : NCUserPermission.self + self.permissions = parentMetadata.directory ? type.forDirectory : type.forFile + self.advanced = share.shareType == NCShareCommon.shared.SHARE_TYPE_LINK ? NCShareDetails.forLink : NCShareDetails.forUser + } + + func cellFor(indexPath: IndexPath) -> UITableViewCell? { + let cellConfig = config(for: indexPath) + let cell = cellConfig?.getCell(for: share) + cell?.textLabel?.text = cellConfig?.title + if let cellConfig = cellConfig as? NCPermission, !cellConfig.hasResharePermission(for: resharePermission) { + cell?.isUserInteractionEnabled = false + cell?.textLabel?.isEnabled = false + } + return cell + } + + func didSelectRow(at indexPath: IndexPath) { + let cellConfig = config(for: indexPath) + cellConfig?.didSelect(for: share) + } + + func config(for indexPath: IndexPath) -> NCShareCellConfig? { + if indexPath.section == 0, indexPath.row < permissions.count { + return permissions[indexPath.row] + } else if indexPath.section == 1, indexPath.row < advanced.count { + return advanced[indexPath.row] + } else { return nil } + } +} + +class NCShareToggleCell: UITableViewCell { + typealias CustomToggleIcon = (onIconName: String?, offIconName: String?) + init(isOn: Bool, customIcons: CustomToggleIcon? = nil) { + super.init(style: .default, reuseIdentifier: "toggleCell") + guard let customIcons = customIcons, + let iconName = isOn ? customIcons.onIconName : customIcons.offIconName else { + self.accessoryType = isOn ? .checkmark : .none + return + } + let image = NCUtility.shared.loadImage(named: iconName, color: NCBrandColor.shared.brandElement, size: self.frame.height - 26) + self.accessoryView = UIImageView(image: image) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +class NCShareDateCell: UITableViewCell { + let picker = UIDatePicker() + let textField = UITextField() + + var onReload: (() -> Void)? + + init(share: NCTableShareable) { + super.init(style: .value1, reuseIdentifier: "shareExpDate") + picker.datePickerMode = .date + picker.minimumDate = Date() + if #available(iOS 13.4, *) { + picker.preferredDatePickerStyle = .wheels + } + picker.action(for: .valueChanged) { datePicker in + guard let datePicker = datePicker as? UIDatePicker else { return } + self.detailTextLabel?.text = DateFormatter.shareExpDate.string(from: datePicker.date) + } + accessoryView = textField + + let toolbar = UIToolbar.toolbar { + self.resignFirstResponder() + share.expirationDate = nil + self.onReload?() + } completion: { + self.resignFirstResponder() + share.expirationDate = self.picker.date as NSDate + self.onReload?() + } + + textField.inputAccessoryView = toolbar.wrappedSafeAreaContainer + textField.inputView = picker + + if let expDate = share.expirationDate { + detailTextLabel?.text = DateFormatter.shareExpDate.string(from: expDate as Date) + } + } + + required public init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/iOSClient/Share/Advanced/NCShareNewUserAddComment.swift b/iOSClient/Share/Advanced/NCShareNewUserAddComment.swift new file mode 100644 index 000000000..73af68588 --- /dev/null +++ b/iOSClient/Share/Advanced/NCShareNewUserAddComment.swift @@ -0,0 +1,95 @@ +// +// NCShareNewUserAddComment.swift +// Nextcloud +// +// Created by TSI-mc on 21/06/21. +// Copyright © 2022 Henrik Storch. All rights reserved. +// +// Author Henrik Storch <henrik.storch@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 UIKit +import NCCommunication +import SVGKit + +class NCShareNewUserAddComment: UIViewController, NCShareDetail { + + @IBOutlet weak var headerContainerView: UIView! + @IBOutlet weak var sharingLabel: UILabel! + @IBOutlet weak var noteTextField: UITextView! + + let contentInsets: CGFloat = 16 + var onDismiss: (() -> Void)? + + public var share: NCTableShareable! + public var metadata: tableMetadata! + + override func viewDidLoad() { + super.viewDidLoad() + self.setNavigationTitle() + + NotificationCenter.default.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil) + + sharingLabel.text = NSLocalizedString("_share_note_recipient_", comment: "") + + noteTextField.textContainerInset = UIEdgeInsets(top: contentInsets, left: contentInsets, bottom: contentInsets, right: contentInsets) + noteTextField.text = share.note + let toolbar = UIToolbar.toolbar { + self.noteTextField.resignFirstResponder() + self.noteTextField.text = "" + self.share.note = "" + } completion: { + self.noteTextField.resignFirstResponder() + self.share.note = self.noteTextField.text + } + + noteTextField.inputAccessoryView = toolbar.wrappedSafeAreaContainer + + guard let headerView = (Bundle.main.loadNibNamed("NCShareAdvancePermissionHeader", owner: self, options: nil)?.first as? NCShareAdvancePermissionHeader) else { return } + headerContainerView.addSubview(headerView) + headerView.frame = headerContainerView.frame + headerView.translatesAutoresizingMaskIntoConstraints = false + headerView.topAnchor.constraint(equalTo: headerContainerView.topAnchor).isActive = true + headerView.bottomAnchor.constraint(equalTo: headerContainerView.bottomAnchor).isActive = true + headerView.leftAnchor.constraint(equalTo: headerContainerView.leftAnchor).isActive = true + headerView.rightAnchor.constraint(equalTo: headerContainerView.rightAnchor).isActive = true + + headerView.setupUI(with: metadata) + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + share.note = noteTextField.text + onDismiss?() + } + + @objc func adjustForKeyboard(notification: Notification) { + guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue, + let globalTextViewFrame = noteTextField.superview?.convert(noteTextField.frame, to: nil) else { return } + + let keyboardScreenEndFrame = keyboardValue.cgRectValue + let portionCovoredByLeyboard = globalTextViewFrame.maxY - keyboardScreenEndFrame.minY + + if notification.name == UIResponder.keyboardWillHideNotification || portionCovoredByLeyboard < 0 { + noteTextField.contentInset = .zero + } else { + noteTextField.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: portionCovoredByLeyboard, right: 0) + } + + noteTextField.scrollIndicatorInsets = noteTextField.contentInset + } +} diff --git a/iOSClient/Share/NCShareUserDropDownCell.xib b/iOSClient/Share/NCSearchUserDropDownCell.xib index 9701c08c8..fa63960bc 100755 --- a/iOSClient/Share/NCShareUserDropDownCell.xib +++ b/iOSClient/Share/NCSearchUserDropDownCell.xib @@ -1,15 +1,15 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES"> <device id="retina4_7" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/> <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 contentMode="scaleToFill" id="iN0-l3-epB" customClass="NCShareUserDropDownCell" customModule="Nextcloud" customModuleProvider="target"> + <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="NCSearchUserDropDownCell" customModule="Nextcloud" customModuleProvider="target"> <rect key="frame" x="0.0" y="0.0" width="487" height="50"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> diff --git a/iOSClient/Share/NCShare+Helper.swift b/iOSClient/Share/NCShare+Helper.swift new file mode 100644 index 000000000..bb108652c --- /dev/null +++ b/iOSClient/Share/NCShare+Helper.swift @@ -0,0 +1,109 @@ +// +// NCShare+Helper.swift +// Nextcloud +// +// Created by Henrik Storch on 19.03.22. +// Copyright © 2022 Henrik Storch. All rights reserved. +// +// Author Henrik Storch <henrik.storch@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 UIKit +import NCCommunication + +extension tableShare: NCTableShareable { } +extension NCCommunicationShare: NCTableShareable { } + +protocol NCTableShareable: AnyObject { + var shareType: Int { get set } + var permissions: Int { get set } + + var idShare: Int { get set } + var shareWith: String { get set } + + var hideDownload: Bool { get set } + var password: String { get set } + var label: String { get set } + var note: String { get set } + var expirationDate: NSDate? { get set } + var shareWithDisplayname: String { get set } +} + +extension NCTableShareable { + var expDateString: String? { + guard let date = expirationDate else { return nil } + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss" + return dateFormatter.string(from: date as Date) + } + + func hasChanges(comparedTo other: NCTableShareable) -> Bool { + return other.shareType != shareType + || other.permissions != permissions + || other.hideDownload != hideDownload + || other.password != password + || other.label != label + || other.note != note + || other.expirationDate != expirationDate + } +} + +class NCTableShareOptions: NCTableShareable { + var shareType: Int + var permissions: Int + + var idShare: Int = 0 + var shareWith: String = "" + + var hideDownload: Bool = false + var password: String = "" + var label: String = "" + var note: String = "" + var expirationDate: NSDate? + var shareWithDisplayname: String = "" + + private init(shareType: Int, metadata: tableMetadata, password: String?) { + self.permissions = NCManageDatabase.shared.getCapabilitiesServerInt(account: metadata.account, elements: ["ocs", "data", "capabilities", "files_sharing", "default_permissions"]) & metadata.sharePermissionsCollaborationServices + self.shareType = shareType + if let password = password { + self.password = password + } + } + + convenience init(sharee: NCCommunicationSharee, metadata: tableMetadata, password: String?) { + self.init(shareType: sharee.shareType, metadata: metadata, password: password) + self.shareWith = sharee.shareWith + } + + static func shareLink(metadata: tableMetadata, password: String?) -> NCTableShareOptions { + return NCTableShareOptions(shareType: NCShareCommon.shared.SHARE_TYPE_LINK, metadata: metadata, password: password) + } +} + +protocol NCShareDetail { + var share: NCTableShareable! { get } +} + +extension NCShareDetail where Self: UIViewController { + func setNavigationTitle() { + title = NSLocalizedString("_share_", comment: "") + " – " + if share.shareType == NCShareCommon.shared.SHARE_TYPE_LINK { + title! += share.label.isEmpty ? NSLocalizedString("_share_link_", comment: "") : share.label + } else { + title! += share.shareWithDisplayname.isEmpty ? share.shareWith : share.shareWithDisplayname + } + } +} diff --git a/iOSClient/Share/NCShare+NCCellDelegate.swift b/iOSClient/Share/NCShare+NCCellDelegate.swift new file mode 100644 index 000000000..78dfd1074 --- /dev/null +++ b/iOSClient/Share/NCShare+NCCellDelegate.swift @@ -0,0 +1,69 @@ +// +// NCShare+NCCellDelegate.swift +// Nextcloud +// +// Created by Henrik Storch on 03.01.22. +// Copyright © 2022 Henrik Storch. All rights reserved. +// +// Author Henrik Storch <henrik.storch@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 UIKit + +// MARK: - NCCell Delegates +extension NCShare: NCShareLinkCellDelegate, NCShareUserCellDelegate { + + func copyInternalLink(sender: Any) { + guard let metadata = self.metadata, let appDelegate = appDelegate else { return } + + let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName + NCNetworking.shared.readFile(serverUrlFileName: serverUrlFileName, account: metadata.account) { _, metadata, errorCode, errorDescription in + if errorCode == 0, let metadata = metadata { + let internalLink = appDelegate.urlBase + "/index.php/f/" + metadata.fileId + NCShareCommon.shared.copyLink(link: internalLink, viewController: self, sender: sender) + } else { + NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode) + } + } + } + + func tapCopy(with tableShare: tableShare?, sender: Any) { + guard let tableShare = tableShare else { + return copyInternalLink(sender: sender) + } + NCShareCommon.shared.copyLink(link: tableShare.url, viewController: self, sender: sender) + } + + func tapMenu(with tableShare: tableShare?, sender: Any) { + if let tableShare = tableShare { + self.toggleShareMenu(for: tableShare) + } else { + self.makeNewLinkShare() + } + } + + func showProfile(with tableShare: tableShare?, sender: Any) { + guard let tableShare = tableShare else { return } + showProfileMenu(userId: tableShare.shareWith) + } + + func quickStatus(with tableShare: tableShare?, sender: Any) { + guard let tableShare = tableShare, + let metadata = metadata, + tableShare.shareType != NCGlobal.shared.permissionDefaultFileRemoteShareNoSupportShareOption else { return } + self.toggleUserPermissionMenu(isDirectory: metadata.directory, tableShare: tableShare) + } +} diff --git a/iOSClient/Share/NCShare.storyboard b/iOSClient/Share/NCShare.storyboard index 23d454487..fa9c539d5 100644 --- a/iOSClient/Share/NCShare.storyboard +++ b/iOSClient/Share/NCShare.storyboard @@ -1,10 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Ts3-RO-A9l"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Ts3-RO-A9l"> <device id="retina5_5" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <scenes> @@ -54,66 +55,9 @@ <rect key="frame" x="5" y="0.0" width="404" height="726"/> <subviews> <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="c94-b9-Sim"> - <rect key="frame" x="0.0" y="250" width="404" height="476"/> + <rect key="frame" x="0.0" y="133" width="404" height="593"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> </tableView> - <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="8Cj-cK-AKZ"> - <rect key="frame" x="5" y="139" width="40" height="40"/> - <constraints> - <constraint firstAttribute="height" constant="40" id="CCv-Uu-Vel"/> - <constraint firstAttribute="width" constant="40" id="egJ-xl-yj4"/> - </constraints> - </imageView> - <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="HPl-mj-r5E"> - <rect key="frame" x="5" y="199" width="40" height="40"/> - <constraints> - <constraint firstAttribute="width" constant="40" id="6IE-lI-M6i"/> - <constraint firstAttribute="height" constant="40" id="Odq-bX-Hoz"/> - </constraints> - </imageView> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Share link" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SQW-aQ-ydN"> - <rect key="frame" x="53" y="150" width="261" height="18"/> - <fontDescription key="fontDescription" type="system" pointSize="15"/> - <nil key="textColor"/> - <nil key="highlightedColor"/> - </label> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Share link" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YYp-o8-YJP"> - <rect key="frame" x="53" y="195" width="317" height="18"/> - <fontDescription key="fontDescription" type="system" pointSize="15"/> - <nil key="textColor"/> - <nil key="highlightedColor"/> - </label> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pfo-D0-W7b"> - <rect key="frame" x="53" y="216.66666666666666" width="317" height="35"/> - <constraints> - <constraint firstAttribute="height" constant="35" id="f8b-mp-xLJ"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="14"/> - <color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> - <nil key="highlightedColor"/> - </label> - <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Qek-aQ-NjE" userLabel="ButtonMenu"> - <rect key="frame" x="374" y="149" width="20" height="20"/> - <constraints> - <constraint firstAttribute="width" constant="20" id="BAT-jK-rUt"/> - <constraint firstAttribute="height" constant="20" id="zc5-W6-SXG"/> - </constraints> - <state key="normal" image="shareMenu"/> - <connections> - <action selector="touchUpInsideButtonMenu:" destination="bgO-Rz-2M1" eventType="touchUpInside" id="ogE-7H-hMG"/> - </connections> - </button> - <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cLd-wD-cSC" userLabel="ButtonCopy"> - <rect key="frame" x="324" y="149" width="20" height="20"/> - <constraints> - <constraint firstAttribute="width" constant="20" id="Bzl-zW-yzd"/> - <constraint firstAttribute="height" constant="20" id="RIV-EC-kwC"/> - </constraints> - <state key="normal" image="shareCopy"/> - <connections> - <action selector="touchUpInsideButtonCopy:" destination="bgO-Rz-2M1" eventType="touchUpInside" id="ccu-6N-Tm4"/> - </connections> - </button> <view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oBQ-TP-qof" userLabel="View Shared with you by"> <rect key="frame" x="-5" y="10" width="409" height="90"/> <subviews> @@ -172,46 +116,17 @@ <action selector="searchFieldDidEndOnExitWithTextField:" destination="bgO-Rz-2M1" eventType="editingDidEndOnExit" id="xH6-YR-5W9"/> </connections> </textField> - <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FFi-7t-C8U" userLabel="ButtonCopy"> - <rect key="frame" x="375" y="209" width="20" height="20"/> - <constraints> - <constraint firstAttribute="height" constant="20" id="0KI-54-GMc"/> - <constraint firstAttribute="width" constant="20" id="fcI-Wc-4GE"/> - </constraints> - <state key="normal" image="shareCopy"/> - <connections> - <action selector="touchUpInsideButtonCopyInernalLink:" destination="bgO-Rz-2M1" eventType="touchUpInside" id="fmb-gx-9PH"/> - </connections> - </button> </subviews> <constraints> <constraint firstItem="oBQ-TP-qof" firstAttribute="top" secondItem="X2m-IC-J1u" secondAttribute="top" constant="10" id="09Y-bm-RvQ"/> - <constraint firstItem="HPl-mj-r5E" firstAttribute="top" secondItem="8Cj-cK-AKZ" secondAttribute="bottom" constant="20" id="0dX-Ni-vDj"/> <constraint firstAttribute="trailing" secondItem="c94-b9-Sim" secondAttribute="trailing" id="BtN-cJ-TTc"/> - <constraint firstItem="c94-b9-Sim" firstAttribute="top" secondItem="iSO-mc-0TB" secondAttribute="bottom" constant="125" id="Co6-l6-HiT"/> - <constraint firstItem="FFi-7t-C8U" firstAttribute="leading" secondItem="YYp-o8-YJP" secondAttribute="trailing" constant="5" id="IE6-R3-yOv"/> - <constraint firstItem="SQW-aQ-ydN" firstAttribute="centerY" secondItem="8Cj-cK-AKZ" secondAttribute="centerY" id="LtS-8d-L7a"/> - <constraint firstItem="Qek-aQ-NjE" firstAttribute="centerY" secondItem="8Cj-cK-AKZ" secondAttribute="centerY" id="NYZ-hc-SBk"/> - <constraint firstItem="SQW-aQ-ydN" firstAttribute="leading" secondItem="8Cj-cK-AKZ" secondAttribute="trailing" constant="8" id="Oby-Ea-MaC"/> - <constraint firstItem="cLd-wD-cSC" firstAttribute="leading" secondItem="SQW-aQ-ydN" secondAttribute="trailing" constant="10" id="PFh-qU-yXY"/> - <constraint firstItem="YYp-o8-YJP" firstAttribute="leading" secondItem="HPl-mj-r5E" secondAttribute="trailing" constant="8" id="R36-FW-w0B"/> - <constraint firstItem="pfo-D0-W7b" firstAttribute="centerY" secondItem="HPl-mj-r5E" secondAttribute="centerY" constant="15" id="Rji-xW-vn7"/> + <constraint firstItem="c94-b9-Sim" firstAttribute="top" secondItem="iSO-mc-0TB" secondAttribute="bottom" constant="8" id="Co6-l6-HiT"/> <constraint firstAttribute="bottom" secondItem="c94-b9-Sim" secondAttribute="bottom" id="Svm-RV-vnl"/> <constraint firstAttribute="trailing" secondItem="iSO-mc-0TB" secondAttribute="trailing" constant="10" id="Vhu-GP-EJN"/> - <constraint firstItem="8Cj-cK-AKZ" firstAttribute="leading" secondItem="X2m-IC-J1u" secondAttribute="leading" constant="5" id="WlZ-CY-x4s"/> <constraint firstAttribute="trailing" secondItem="oBQ-TP-qof" secondAttribute="trailing" id="ZuM-2G-aoM"/> - <constraint firstItem="Qek-aQ-NjE" firstAttribute="leading" secondItem="cLd-wD-cSC" secondAttribute="trailing" constant="30" id="bSw-vM-d12"/> <constraint firstItem="iSO-mc-0TB" firstAttribute="leading" secondItem="X2m-IC-J1u" secondAttribute="leading" constant="5" id="d8E-WM-YfC"/> - <constraint firstItem="FFi-7t-C8U" firstAttribute="centerY" secondItem="HPl-mj-r5E" secondAttribute="centerY" id="fkL-uP-Iob"/> - <constraint firstItem="YYp-o8-YJP" firstAttribute="centerY" secondItem="HPl-mj-r5E" secondAttribute="centerY" constant="-15" id="iu4-c5-p5k"/> <constraint firstItem="iSO-mc-0TB" firstAttribute="top" secondItem="X2m-IC-J1u" secondAttribute="top" constant="95" id="jPM-Uo-0lS"/> - <constraint firstItem="pfo-D0-W7b" firstAttribute="leading" secondItem="HPl-mj-r5E" secondAttribute="trailing" constant="8" symbolic="YES" id="oKN-Ui-VIn"/> - <constraint firstAttribute="trailing" secondItem="Qek-aQ-NjE" secondAttribute="trailing" constant="10" id="puY-4D-ARy"/> <constraint firstItem="c94-b9-Sim" firstAttribute="leading" secondItem="X2m-IC-J1u" secondAttribute="leading" id="rvD-u3-Dug"/> - <constraint firstItem="8Cj-cK-AKZ" firstAttribute="top" secondItem="iSO-mc-0TB" secondAttribute="bottom" constant="14" id="shO-sV-GWB"/> - <constraint firstItem="cLd-wD-cSC" firstAttribute="centerY" secondItem="8Cj-cK-AKZ" secondAttribute="centerY" id="xia-sb-RNk"/> - <constraint firstItem="FFi-7t-C8U" firstAttribute="leading" secondItem="pfo-D0-W7b" secondAttribute="trailing" constant="5" id="zez-7B-WAb"/> - <constraint firstItem="HPl-mj-r5E" firstAttribute="leading" secondItem="X2m-IC-J1u" secondAttribute="leading" constant="5" id="zpN-ax-gny"/> </constraints> </view> </subviews> @@ -223,20 +138,11 @@ <constraint firstItem="X2m-IC-J1u" firstAttribute="top" secondItem="aV2-U6-JTf" secondAttribute="top" id="aXO-v9-CBF"/> <constraint firstItem="eAi-wv-a4Y" firstAttribute="trailing" secondItem="X2m-IC-J1u" secondAttribute="trailing" constant="5" id="hVX-vu-qJn"/> <constraint firstItem="oBQ-TP-qof" firstAttribute="leading" secondItem="eAi-wv-a4Y" secondAttribute="leading" id="r7R-MU-9cw"/> - <constraint firstItem="eAi-wv-a4Y" firstAttribute="trailing" secondItem="FFi-7t-C8U" secondAttribute="trailing" constant="14" id="xLc-ai-2T1"/> </constraints> </view> <connections> - <outlet property="buttonCopy" destination="cLd-wD-cSC" id="Sib-oL-uQx"/> - <outlet property="buttonInternalCopy" destination="FFi-7t-C8U" id="2ez-LZ-iZ0"/> - <outlet property="buttonMenu" destination="Qek-aQ-NjE" id="xfp-a1-YDn"/> <outlet property="searchField" destination="iSO-mc-0TB" id="1vY-Js-dGQ"/> <outlet property="searchFieldTopConstraint" destination="jPM-Uo-0lS" id="yfd-cG-1mu"/> - <outlet property="shareInternalLinkDescription" destination="pfo-D0-W7b" id="uRy-U9-bQu"/> - <outlet property="shareInternalLinkImage" destination="HPl-mj-r5E" id="CDi-ev-3eO"/> - <outlet property="shareInternalLinkLabel" destination="YYp-o8-YJP" id="rir-aT-bt5"/> - <outlet property="shareLinkImage" destination="8Cj-cK-AKZ" id="dIZ-nv-gyf"/> - <outlet property="shareLinkLabel" destination="SQW-aQ-ydN" id="nBK-WJ-oKy"/> <outlet property="sharedWithYouByImage" destination="fKv-xM-rVY" id="EJ0-sV-By8"/> <outlet property="sharedWithYouByLabel" destination="ngi-GT-jvv" id="Qay-IG-tZh"/> <outlet property="sharedWithYouByNote" destination="KHG-xj-wfG" id="4m5-u6-7RW"/> @@ -250,6 +156,130 @@ </objects> <point key="canvasLocation" x="2689.8550724637685" y="-167.41071428571428"/> </scene> + <!--Share New User Add Comment--> + <scene sceneID="JJ2-tz-qZ7"> + <objects> + <viewController storyboardIdentifier="NCShareNewUserAddComment" id="VvU-6J-pzy" customClass="NCShareNewUserAddComment" customModule="Nextcloud" customModuleProvider="target" sceneMemberID="viewController"> + <view key="view" contentMode="scaleToFill" id="EtF-Pb-SYb"> + <rect key="frame" x="0.0" y="0.0" width="414" height="736"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="UNN-v3-g1S"> + <rect key="frame" x="0.0" y="0.0" width="414" height="736"/> + <subviews> + <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="rZ9-oE-c21"> + <rect key="frame" x="0.0" y="0.0" width="414" height="736"/> + <subviews> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qVy-Qr-W7j"> + <rect key="frame" x="0.0" y="0.0" width="414" height="200"/> + <color key="backgroundColor" systemColor="systemBackgroundColor"/> + <constraints> + <constraint firstAttribute="height" constant="200" id="GX8-Mb-uqf"/> + </constraints> + </view> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YMG-hf-HEX"> + <rect key="frame" x="0.0" y="200" width="414" height="536"/> + <subviews> + <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" canCancelContentTouches="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="VT0-1l-5HI"> + <rect key="frame" x="16" y="60.333333333333286" width="382" height="423.66666666666674"/> + <color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/> + <constraints> + <constraint firstAttribute="height" relation="greaterThanOrEqual" constant="100" id="wqE-G9-M95"/> + </constraints> + <inset key="scrollIndicatorInsets" minX="0.0" minY="0.0" maxX="10" maxY="0.0"/> + <color key="textColor" systemColor="labelColor"/> + <fontDescription key="fontDescription" type="system" pointSize="14"/> + <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/> + <userDefinedRuntimeAttributes> + <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius"> + <integer key="value" value="10"/> + </userDefinedRuntimeAttribute> + </userDefinedRuntimeAttributes> + <connections> + <outlet property="delegate" destination="VvU-6J-pzy" id="cAt-UZ-6KT"/> + </connections> + </textView> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Sharing" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vkm-Pe-6qd"> + <rect key="frame" x="16.000000000000004" y="24" width="61.333333333333343" height="20.333333333333329"/> + <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + </subviews> + <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstItem="vkm-Pe-6qd" firstAttribute="leading" secondItem="YMG-hf-HEX" secondAttribute="leading" constant="16" id="Auk-mC-Mie"/> + <constraint firstAttribute="bottom" secondItem="VT0-1l-5HI" secondAttribute="bottom" priority="100" constant="52" id="FYk-Lv-5f6"/> + <constraint firstItem="vkm-Pe-6qd" firstAttribute="top" secondItem="YMG-hf-HEX" secondAttribute="top" constant="24" id="L0w-Cz-uK2"/> + <constraint firstAttribute="trailing" secondItem="VT0-1l-5HI" secondAttribute="trailing" constant="16" id="TgX-1J-iTO"/> + <constraint firstItem="VT0-1l-5HI" firstAttribute="leading" secondItem="YMG-hf-HEX" secondAttribute="leading" constant="16" id="gEq-qv-UTR"/> + <constraint firstItem="VT0-1l-5HI" firstAttribute="top" secondItem="vkm-Pe-6qd" secondAttribute="bottom" constant="16" id="ghe-aR-N1L"/> + <constraint firstAttribute="height" constant="536" id="oYk-ib-hVx"/> + </constraints> + </view> + </subviews> + </stackView> + </subviews> + <constraints> + <constraint firstItem="rZ9-oE-c21" firstAttribute="trailing" secondItem="cdt-uF-sLc" secondAttribute="trailing" id="JLe-cg-49Y"/> + <constraint firstItem="rZ9-oE-c21" firstAttribute="bottom" secondItem="cdt-uF-sLc" secondAttribute="bottom" id="fHi-hu-MpS"/> + <constraint firstItem="rZ9-oE-c21" firstAttribute="top" secondItem="cdt-uF-sLc" secondAttribute="top" id="od8-4k-3u3"/> + <constraint firstItem="rZ9-oE-c21" firstAttribute="width" secondItem="yeM-rG-mCp" secondAttribute="width" id="v9J-mK-SfO"/> + <constraint firstItem="rZ9-oE-c21" firstAttribute="leading" secondItem="cdt-uF-sLc" secondAttribute="leading" id="xze-Xh-I92"/> + </constraints> + <viewLayoutGuide key="contentLayoutGuide" id="cdt-uF-sLc"/> + <viewLayoutGuide key="frameLayoutGuide" id="yeM-rG-mCp"/> + </scrollView> + </subviews> + <viewLayoutGuide key="safeArea" id="8hH-o3-iQD"/> + <color key="backgroundColor" systemColor="systemBackgroundColor"/> + <constraints> + <constraint firstItem="UNN-v3-g1S" firstAttribute="top" secondItem="8hH-o3-iQD" secondAttribute="top" id="UD6-u2-ckg"/> + <constraint firstItem="8hH-o3-iQD" firstAttribute="bottom" secondItem="UNN-v3-g1S" secondAttribute="bottom" id="WzJ-jl-e33"/> + <constraint firstItem="VT0-1l-5HI" firstAttribute="height" relation="lessThanOrEqual" secondItem="EtF-Pb-SYb" secondAttribute="height" constant="-150" id="h3K-2H-qDr"/> + <constraint firstItem="UNN-v3-g1S" firstAttribute="leading" secondItem="8hH-o3-iQD" secondAttribute="leading" id="r39-yL-F9v"/> + <constraint firstItem="8hH-o3-iQD" firstAttribute="trailing" secondItem="UNN-v3-g1S" secondAttribute="trailing" id="rNm-B2-hl3"/> + </constraints> + </view> + <navigationItem key="navigationItem" id="uC3-gg-Wos"/> + <connections> + <outlet property="headerContainerView" destination="qVy-Qr-W7j" id="LaE-WS-v1X"/> + <outlet property="noteTextField" destination="VT0-1l-5HI" id="Ilz-T9-5BL"/> + <outlet property="sharingLabel" destination="vkm-Pe-6qd" id="NVy-Ug-ipx"/> + </connections> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="LJ3-hs-98b" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="4261" y="-168"/> + </scene> + <!--Share Advance Permission--> + <scene sceneID="59b-BB-FLA"> + <objects> + <tableViewController storyboardIdentifier="NCShareAdvancePermission" id="r5U-VP-Qhs" customClass="NCShareAdvancePermission" customModule="Nextcloud" customModuleProvider="target" sceneMemberID="viewController"> + <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" id="lDu-k5-2hT"> + <rect key="frame" x="0.0" y="0.0" width="414" height="736"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <color key="backgroundColor" systemColor="systemBackgroundColor"/> + <prototypes> + <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="0qP-1F-pHW"> + <rect key="frame" x="0.0" y="44.666666030883789" width="414" height="43.666667938232422"/> + <autoresizingMask key="autoresizingMask"/> + <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="0qP-1F-pHW" id="z1u-eI-gTZ"> + <rect key="frame" x="0.0" y="0.0" width="414" height="43.666667938232422"/> + <autoresizingMask key="autoresizingMask"/> + </tableViewCellContentView> + </tableViewCell> + </prototypes> + <connections> + <outlet property="dataSource" destination="r5U-VP-Qhs" id="OET-a5-qea"/> + <outlet property="delegate" destination="r5U-VP-Qhs" id="cDp-4z-0Xt"/> + </connections> + </tableView> + </tableViewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="ITy-jR-JVD" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="3510" y="-169"/> + </scene> </scenes> <designables> <designable name="KHG-xj-wfG"> @@ -258,7 +288,14 @@ </designables> <resources> <image name="note.text" width="24" height="24"/> - <image name="shareCopy" width="329" height="329"/> - <image name="shareMenu" width="329" height="329"/> + <systemColor name="labelColor"> + <color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </systemColor> + <systemColor name="secondarySystemBackgroundColor"> + <color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + </systemColor> + <systemColor name="systemBackgroundColor"> + <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + </systemColor> </resources> </document> diff --git a/iOSClient/Share/NCShare.swift b/iOSClient/Share/NCShare.swift index b43ce3e48..6ea0a7ef1 100644 --- a/iOSClient/Share/NCShare.swift +++ b/iOSClient/Share/NCShare.swift @@ -4,6 +4,7 @@ // // Created by Marino Faggiana on 17/07/2019. // Copyright © 2019 Marino Faggiana. All rights reserved. +// Copyright © 2022 Henrik Storch. All rights reserved. // // Author Marino Faggiana <marino.faggiana@nextcloud.com> // Author Henrik Storch <henrik.storch@nextcloud.com> @@ -28,7 +29,7 @@ import DropDown import NCCommunication import MarqueeLabel -class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareNetworkingDelegate { +class NCShare: UIViewController, NCShareNetworkingDelegate, NCSharePagingContent { @IBOutlet weak var viewContainerConstraint: NSLayoutConstraint! @IBOutlet weak var sharedWithYouByView: UIView! @@ -38,27 +39,25 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareNetworkingD @IBOutlet weak var sharedWithYouByNote: MarqueeLabel! @IBOutlet weak var searchFieldTopConstraint: NSLayoutConstraint! @IBOutlet weak var searchField: UITextField! - @IBOutlet weak var shareLinkImage: UIImageView! - @IBOutlet weak var shareLinkLabel: UILabel! - @IBOutlet weak var shareInternalLinkImage: UIImageView! - @IBOutlet weak var shareInternalLinkLabel: UILabel! - @IBOutlet weak var shareInternalLinkDescription: UILabel! - @IBOutlet weak var buttonInternalCopy: UIButton! - @IBOutlet weak var buttonCopy: UIButton! - @IBOutlet weak var buttonMenu: UIButton! + var textField: UITextField? { searchField } + @IBOutlet weak var tableView: UITableView! - private let appDelegate = UIApplication.shared.delegate as! AppDelegate + weak var appDelegate = UIApplication.shared.delegate as? AppDelegate public var metadata: tableMetadata? public var sharingEnabled = true public var height: CGFloat = 0 - private var shareLinkMenuView: NCShareLinkMenuView? - private var shareUserMenuView: NCShareUserMenuView? - private var shareMenuViewWindow: UIView? + var canReshare: Bool { + guard let metadata = metadata else { return true } + return ((metadata.sharePermissionsCollaborationServices & NCGlobal.shared.permissionShareShare) != 0) + } + + var shares: (firstShareLink: tableShare?, share: [tableShare]?) = (nil, nil) + private var dropDown = DropDown() - private var networking: NCShareNetworking? + var networking: NCShareNetworking? // MARK: - View Life Cycle @@ -72,16 +71,6 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareNetworkingD searchField.placeholder = NSLocalizedString("_shareLinksearch_placeholder_", comment: "") - shareLinkImage.image = NCShareCommon.shared.createLinkAvatar(imageName: "sharebylink", colorCircle: NCBrandColor.shared.brandElement) - shareLinkLabel.text = NSLocalizedString("_share_link_", comment: "") - shareLinkLabel.textColor = NCBrandColor.shared.label - buttonCopy.setImage(UIImage(named: "shareCopy")?.image(color: .gray, size: 50), for: .normal) - - shareInternalLinkImage.image = NCShareCommon.shared.createLinkAvatar(imageName: "shareInternalLink", colorCircle: .gray) - shareInternalLinkLabel.text = NSLocalizedString("_share_internal_link_", comment: "") - shareInternalLinkDescription.text = NSLocalizedString("_share_internal_link_des_", comment: "") - buttonInternalCopy.setImage(UIImage(named: "shareCopy")?.image(color: .gray, size: 50), for: .normal) - tableView.dataSource = self tableView.delegate = self tableView.allowsSelection = false @@ -92,58 +81,13 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareNetworkingD NotificationCenter.default.addObserver(self, selector: #selector(reloadData), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterReloadDataNCShare), object: nil) - // Shared with you by ... - if let metadata = metadata, !metadata.ownerId.isEmpty, metadata.ownerId != self.appDelegate.userId { - - searchFieldTopConstraint.constant = 65 - sharedWithYouByView.isHidden = false - sharedWithYouByLabel.text = NSLocalizedString("_shared_with_you_by_", comment: "") + " " + metadata.ownerDisplayName - sharedWithYouByImage.image = NCUtility.shared.loadUserImage( - for: metadata.ownerId, - displayName: metadata.ownerDisplayName, - userBaseUrl: appDelegate) - let shareAction = UITapGestureRecognizer(target: self, action: #selector(openShareProfile)) - sharedWithYouByImage.addGestureRecognizer(shareAction) - let shareLabelAction = UITapGestureRecognizer(target: self, action: #selector(openShareProfile)) - sharedWithYouByLabel.addGestureRecognizer(shareLabelAction) - - if metadata.note.count > 0 { - searchFieldTopConstraint.constant = 95 - sharedWithYouByNoteImage.isHidden = false - sharedWithYouByNoteImage.image = NCUtility.shared.loadImage(named: "note.text", color: .gray) - sharedWithYouByNote.isHidden = false - sharedWithYouByNote.text = metadata.note - sharedWithYouByNote.textColor = NCBrandColor.shared.label - sharedWithYouByNote.trailingBuffer = sharedWithYouByNote.frame.width - } else { - sharedWithYouByNoteImage.isHidden = true - sharedWithYouByNote.isHidden = true - } - - let fileName = appDelegate.userBaseUrl + "-" + metadata.ownerId + ".png" - - if NCManageDatabase.shared.getImageAvatarLoaded(fileName: fileName) == nil { - let fileNameLocalPath = String(CCUtility.getDirectoryUserData()) + "/" + fileName - let etag = NCManageDatabase.shared.getTableAvatar(fileName: fileName)?.etag - - NCCommunication.shared.downloadAvatar(user: metadata.ownerId, fileNameLocalPath: fileNameLocalPath, sizeImage: NCGlobal.shared.avatarSize, avatarSizeRounded: NCGlobal.shared.avatarSizeRounded, etag: etag) { _, imageAvatar, _, etag, errorCode, _ in - - if errorCode == 0, let etag = etag, let imageAvatar = imageAvatar { - - NCManageDatabase.shared.addAvatar(fileName: fileName, etag: etag) - self.sharedWithYouByImage.image = imageAvatar - - } else if errorCode == NCGlobal.shared.errorNotModified, let imageAvatar = NCManageDatabase.shared.setAvatarLoaded(fileName: fileName) { + guard let appDelegate = appDelegate, let metadata = metadata else { return } - self.sharedWithYouByImage.image = imageAvatar - } - } - } - } + checkSharedWithYou() reloadData() - networking = NCShareNetworking(metadata: metadata!, urlBase: appDelegate.urlBase, view: self.view, delegate: self) + networking = NCShareNetworking(metadata: metadata, urlBase: appDelegate.urlBase, view: self.view, delegate: self) if sharingEnabled { let isVisible = (self.navigationController?.topViewController as? NCSharePaging)?.indexPage == .sharing networking?.readShare(showLoadingIndicator: isVisible) @@ -151,11 +95,79 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareNetworkingD // changeTheming NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterChangeTheming), object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(changePermissions(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterShareChangePermissions), object: nil) changeTheming() } + func makeNewLinkShare() { + guard + let advancePermission = UIStoryboard(name: "NCShare", bundle: nil).instantiateViewController(withIdentifier: "NCShareAdvancePermission") as? NCShareAdvancePermission, + let navigationController = self.navigationController, + let metadata = self.metadata else { return } + self.checkEnforcedPassword(shareType: NCShareCommon.shared.SHARE_TYPE_LINK) { password in + advancePermission.networking = self.networking + advancePermission.share = NCTableShareOptions.shareLink(metadata: metadata, password: password) + advancePermission.metadata = self.metadata + navigationController.pushViewController(advancePermission, animated: true) + } + } + + // Shared with you by ... + func checkSharedWithYou() { + guard let appDelegate = self.appDelegate, let metadata = metadata, !metadata.ownerId.isEmpty, metadata.ownerId != appDelegate.userId else { return } + + if !canReshare { + searchField.isEnabled = false + searchField.placeholder = NSLocalizedString("_share_reshare_disabled_", comment: "") + } + + searchFieldTopConstraint.constant = 65 + sharedWithYouByView.isHidden = false + sharedWithYouByLabel.text = NSLocalizedString("_shared_with_you_by_", comment: "") + " " + metadata.ownerDisplayName + sharedWithYouByImage.image = NCUtility.shared.loadUserImage( + for: metadata.ownerId, + displayName: metadata.ownerDisplayName, + userBaseUrl: appDelegate) + let shareAction = UITapGestureRecognizer(target: self, action: #selector(openShareProfile)) + sharedWithYouByImage.addGestureRecognizer(shareAction) + let shareLabelAction = UITapGestureRecognizer(target: self, action: #selector(openShareProfile)) + sharedWithYouByLabel.addGestureRecognizer(shareLabelAction) + + if !metadata.note.isEmpty { + searchFieldTopConstraint.constant = 95 + sharedWithYouByNoteImage.isHidden = false + sharedWithYouByNoteImage.image = NCUtility.shared.loadImage(named: "note.text", color: .gray) + sharedWithYouByNote.isHidden = false + sharedWithYouByNote.text = metadata.note + sharedWithYouByNote.textColor = NCBrandColor.shared.label + sharedWithYouByNote.trailingBuffer = sharedWithYouByNote.frame.width + } else { + sharedWithYouByNoteImage.isHidden = true + sharedWithYouByNote.isHidden = true + } + + let fileName = appDelegate.userBaseUrl + "-" + metadata.ownerId + ".png" + + if NCManageDatabase.shared.getImageAvatarLoaded(fileName: fileName) == nil { + let fileNameLocalPath = String(CCUtility.getDirectoryUserData()) + "/" + fileName + let etag = NCManageDatabase.shared.getTableAvatar(fileName: fileName)?.etag + + NCCommunication.shared.downloadAvatar( + user: metadata.ownerId, + fileNameLocalPath: fileNameLocalPath, + sizeImage: NCGlobal.shared.avatarSize, + avatarSizeRounded: NCGlobal.shared.avatarSizeRounded, + etag: etag) { _, imageAvatar, _, etag, errorCode, _ in + if errorCode == 0, let etag = etag, let imageAvatar = imageAvatar { + NCManageDatabase.shared.addAvatar(fileName: fileName, etag: etag) + self.sharedWithYouByImage.image = imageAvatar + } else if errorCode == NCGlobal.shared.errorNotModified, let imageAvatar = NCManageDatabase.shared.setAvatarLoaded(fileName: fileName) { + self.sharedWithYouByImage.image = imageAvatar + } + } + } + } + // MARK: - Notification Center @objc func openShareProfile() { @@ -167,34 +179,11 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareNetworkingD tableView.reloadData() } - @objc func changePermissions(_ notification: NSNotification) { - - if let userInfo = notification.userInfo as NSDictionary? { - if let idShare = userInfo["idShare"] as? Int, let permissions = userInfo["permissions"] as? Int, let hideDownload = userInfo["hideDownload"] as? Bool { - networking?.updateShare(idShare: idShare, password: nil, permissions: permissions, note: nil, label: nil, expirationDate: nil, hideDownload: hideDownload) - } - } - } - // MARK: - @objc func reloadData() { - let shares = NCManageDatabase.shared.getTableShares(metadata: metadata!) - if shares.firstShareLink == nil { - buttonMenu.setImage(UIImage(named: "shareAdd")?.image(color: .gray, size: 50), for: .normal) - buttonCopy.isHidden = true - } else { - buttonMenu.setImage(UIImage(named: "shareMenu")?.image(color: .gray, size: 50), for: .normal) - buttonCopy.isHidden = false - - shareLinkLabel.text = NSLocalizedString("_share_link_", comment: "") - if shares.firstShareLink?.label.count ?? 0 > 0 { - if let shareLinkLabel = shareLinkLabel { - if let label = shares.firstShareLink?.label { - shareLinkLabel.text = NSLocalizedString("_share_link_", comment: "") + " (" + label + ")" - } - } - } + if let metadata = metadata { + shares = NCManageDatabase.shared.getTableShares(metadata: metadata) } tableView.reloadData() } @@ -202,78 +191,17 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareNetworkingD // MARK: - IBAction @IBAction func searchFieldDidEndOnExit(textField: UITextField) { - - guard let searchString = textField.text else { return } - + guard let searchString = textField.text, !searchString.isEmpty else { return } networking?.getSharees(searchString: searchString) } - @IBAction func touchUpInsideButtonCopy(_ sender: Any) { - - guard let metadata = self.metadata else { return } - - let shares = NCManageDatabase.shared.getTableShares(metadata: metadata) - tapCopy(with: shares.firstShareLink, sender: sender) - } - - @IBAction func touchUpInsideButtonCopyInernalLink(_ sender: Any) { - - guard let metadata = self.metadata else { return } - - let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName - NCNetworking.shared.readFile(serverUrlFileName: serverUrlFileName, account: metadata.account, queue: .main) { _, metadata, errorCode, errorDescription in - if errorCode == 0 && metadata != nil { - let internalLink = self.appDelegate.urlBase + "/index.php/f/" + metadata!.fileId - NCShareCommon.shared.copyLink(link: internalLink, viewController: self, sender: sender) - } else { - NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode) - } - } - } - - func checkEnforcedPassword(callback: @escaping (String?) -> Void) { + func checkEnforcedPassword(shareType: Int, completion: @escaping (String?) -> Void) { guard let metadata = self.metadata, - NCManageDatabase.shared.getCapabilitiesServerBool(account: metadata.account, elements: NCElementsJSON.shared.capabilitiesFileSharingPubPasswdEnforced, exists: false) - else { return callback(nil) } - - let alertController = UIAlertController(title: NSLocalizedString("_enforce_password_protection_", comment: ""), message: "", preferredStyle: .alert) - alertController.addTextField { textField in - textField.isSecureTextEntry = true - } - alertController.addAction(UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .default) { _ in }) - let okAction = UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default) { _ in - let password = alertController.textFields?.first?.text - callback(password) - } + NCManageDatabase.shared.getCapabilitiesServerBool(account: metadata.account, elements: NCElementsJSON.shared.capabilitiesFileSharingPubPasswdEnforced, exists: false), + shareType == NCShareCommon.shared.SHARE_TYPE_LINK || shareType == NCShareCommon.shared.SHARE_TYPE_EMAIL + else { return completion(nil) } - alertController.addAction(okAction) - - self.present(alertController, animated: true, completion:nil) - } - - @IBAction func touchUpInsideButtonMenu(_ sender: Any) { - - guard let metadata = self.metadata else { return } - let shares = NCManageDatabase.shared.getTableShares(metadata: metadata) - - if shares.firstShareLink == nil { - checkEnforcedPassword { password in - self.networking?.createShareLink(password: password) - } - } else { - tapMenu(with: shares.firstShareLink!, sender: sender) - } - } - - @objc func tapLinkMenuViewWindow(gesture: UITapGestureRecognizer) { - shareLinkMenuView?.unLoad() - shareLinkMenuView = nil - shareUserMenuView?.unLoad() - shareUserMenuView = nil - } - - func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { - return gestureRecognizer.view == touch.view + self.present(UIAlertController.password(titleKey: "_enforce_password_protection_", completion: completion), animated: true) } // MARK: - NCShareNetworkingDelegate @@ -286,7 +214,9 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareNetworkingD NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataNCShare) } - func unShareCompleted() { } + func unShareCompleted() { + self.reloadData() + } func updateShareWithError(idShare: Int) { self.reloadData() @@ -294,7 +224,7 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareNetworkingD func getSharees(sharees: [NCCommunicationSharee]?) { - guard let sharees = sharees else { return } + guard let sharees = sharees, let appDelegate = appDelegate else { return } dropDown = DropDown() let appearance = DropDown.appearance() @@ -311,7 +241,7 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareNetworkingD for sharee in sharees { var label = sharee.label if sharee.shareType == NCShareCommon.shared.SHARE_TYPE_CIRCLE { - label += " (" + sharee.circleInfo + ", " + sharee.circleOwner + ")" + label += " (\(sharee.circleInfo), \(sharee.circleOwner))" } dropDown.dataSource.append(label) } @@ -321,50 +251,25 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareNetworkingD dropDown.width = searchField.bounds.width dropDown.direction = .bottom - dropDown.cellNib = UINib(nibName: "NCShareUserDropDownCell", bundle: nil) - dropDown.customCellConfiguration = { (index: Index, _: String, cell: DropDownCell) -> Void in - guard let cell = cell as? NCShareUserDropDownCell else { return } + dropDown.cellNib = UINib(nibName: "NCSearchUserDropDownCell", bundle: nil) + dropDown.customCellConfiguration = { (index: Index, _, cell: DropDownCell) -> Void in + guard let cell = cell as? NCSearchUserDropDownCell else { return } let sharee = sharees[index] - cell.imageItem.image = NCShareCommon.shared.getImageShareType(shareType: sharee.shareType) - cell.imageShareeType.image = NCShareCommon.shared.getImageShareType(shareType: sharee.shareType) - let status = NCUtility.shared.getUserStatus(userIcon: sharee.userIcon, userStatus: sharee.userStatus, userMessage: sharee.userMessage) - cell.imageStatus.image = status.onlineStatus - cell.status.text = status.statusMessage - if cell.status.text?.count ?? 0 > 0 { - cell.centerTitle.constant = -5 - } else { - cell.centerTitle.constant = 0 - } - - cell.imageItem.image = NCUtility.shared.loadUserImage( - for: sharee.shareWith, - displayName: nil, - userBaseUrl: self.appDelegate) - - let fileName = self.appDelegate.userBaseUrl + "-" + sharee.shareWith + ".png" - if NCManageDatabase.shared.getImageAvatarLoaded(fileName: fileName) == nil { - let fileNameLocalPath = String(CCUtility.getDirectoryUserData()) + "/" + fileName - let etag = NCManageDatabase.shared.getTableAvatar(fileName: fileName)?.etag - - NCCommunication.shared.downloadAvatar(user: sharee.shareWith, fileNameLocalPath: fileNameLocalPath, sizeImage: NCGlobal.shared.avatarSize, avatarSizeRounded: NCGlobal.shared.avatarSizeRounded, etag: etag) { _, imageAvatar, _, etag, errorCode, _ in - - if errorCode == 0, let etag = etag, let imageAvatar = imageAvatar { - - NCManageDatabase.shared.addAvatar(fileName: fileName, etag: etag) - cell.imageItem.image = imageAvatar - - } else if errorCode == NCGlobal.shared.errorNotModified, let imageAvatar = NCManageDatabase.shared.setAvatarLoaded(fileName: fileName) { - - cell.imageItem.image = imageAvatar - } - } - } + cell.setupCell(sharee: sharee, baseUrl: appDelegate) } - dropDown.selectionAction = { (index, item) in + dropDown.selectionAction = { index, _ in let sharee = sharees[index] - self.checkEnforcedPassword { password in - self.networking?.createShare(shareWith: sharee.shareWith, shareType: sharee.shareType, password: password, metadata: self.metadata!) + guard + let advancePermission = UIStoryboard(name: "NCShare", bundle: nil).instantiateViewController(withIdentifier: "NCShareAdvancePermission") as? NCShareAdvancePermission, + let navigationController = self.navigationController, + let metadata = self.metadata else { return } + self.checkEnforcedPassword(shareType: sharee.shareType) { password in + let shareOptions = NCTableShareOptions(sharee: sharee, metadata: metadata, password: password) + advancePermission.share = shareOptions + advancePermission.networking = self.networking + advancePermission.metadata = metadata + navigationController.pushViewController(advancePermission, animated: true) } } @@ -377,6 +282,10 @@ class NCShare: UIViewController, UIGestureRecognizerDelegate, NCShareNetworkingD extension NCShare: UITableViewDelegate { func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + if indexPath.section == 0, indexPath.row == 0 { + // internal cell has description + return 90 + } return 70 } } @@ -386,82 +295,48 @@ extension NCShare: UITableViewDelegate { extension NCShare: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { - return 1 + return 2 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - - var numOfRows = 0 - let shares = NCManageDatabase.shared.getTableShares(metadata: metadata!) - - if shares.share != nil { - numOfRows = shares.share!.count - } - - return numOfRows + // don't allow link creation if reshare is disabled + guard section != 0 else { return shares.firstShareLink != nil || canReshare ? 2 : 1 } + return shares.share?.count ?? 0 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + // Setup default share cells + guard indexPath.section != 0 else { + guard let cell = tableView.dequeueReusableCell(withIdentifier: "cellLink", for: indexPath) as? NCShareLinkCell + else { return UITableViewCell() } + cell.delegate = self + if indexPath.row == 0 { + cell.isInternalLink = true + } else if shares.firstShareLink?.isInvalidated != true { + cell.tableShare = shares.firstShareLink + } + cell.setupCellUI() + return cell + } - let shares = NCManageDatabase.shared.getTableShares(metadata: metadata!) - let tableShare = shares.share![indexPath.row] + guard let appDelegate = appDelegate, let tableShare = shares.share?[indexPath.row] else { return UITableViewCell() } // LINK - if tableShare.shareType == 3 { + if tableShare.shareType == NCShareCommon.shared.SHARE_TYPE_LINK { if let cell = tableView.dequeueReusableCell(withIdentifier: "cellLink", for: indexPath) as? NCShareLinkCell { cell.tableShare = tableShare cell.delegate = self - cell.labelTitle.text = NSLocalizedString("_share_link_", comment: "") - if tableShare.label.count > 0 { - cell.labelTitle.text = NSLocalizedString("_share_link_", comment: "") + " (" + tableShare.label + ")" - } - cell.labelTitle.textColor = NCBrandColor.shared.label + cell.setupCellUI() return cell } } else { - // USER + // USER / GROUP etc. if let cell = tableView.dequeueReusableCell(withIdentifier: "cellUser", for: indexPath) as? NCShareUserCell { - cell.tableShare = tableShare cell.delegate = self - cell.labelTitle.text = tableShare.shareWithDisplayname - cell.labelTitle.textColor = NCBrandColor.shared.label - cell.isUserInteractionEnabled = true - cell.labelQuickStatus.isHidden = false - cell.imageDownArrow.isHidden = false - cell.buttonMenu.isHidden = false - cell.imageItem.image = NCShareCommon.shared.getImageShareType(shareType: tableShare.shareType) - - let status = NCUtility.shared.getUserStatus(userIcon: tableShare.userIcon, userStatus: tableShare.userStatus, userMessage: tableShare.userMessage) - cell.imageStatus.image = status.onlineStatus - cell.status.text = status.statusMessage - + cell.setupCellUI(userId: appDelegate.userId) let fileName = appDelegate.userBaseUrl + "-" + tableShare.shareWith + ".png" - NCOperationQueue.shared.downloadAvatar(user: tableShare.shareWith, dispalyName: tableShare.shareWithDisplayname, fileName: fileName, cell: cell, view: tableView) - - // If the initiator or the recipient is not the current user, show the list of sharees without any options to edit it. - if tableShare.uidOwner != self.appDelegate.userId && tableShare.uidFileOwner != self.appDelegate.userId { - cell.isUserInteractionEnabled = false - cell.labelQuickStatus.isHidden = true - cell.imageDownArrow.isHidden = true - cell.buttonMenu.isHidden = true - } - - cell.btnQuickStatus.setTitle("", for: .normal) - cell.btnQuickStatus.contentHorizontalAlignment = .left - - if tableShare.permissions == NCGlobal.shared.permissionCreateShare { - cell.labelQuickStatus.text = NSLocalizedString("_share_file_drop_", comment: "") - } else { - // Read Only - if CCUtility.isAnyPermission(toEdit: tableShare.permissions) { - cell.labelQuickStatus.text = NSLocalizedString("_share_editing_", comment: "") - } else { - cell.labelQuickStatus.text = NSLocalizedString("_share_read_only_", comment: "") - } - } - return cell } } @@ -469,53 +344,3 @@ extension NCShare: UITableViewDataSource { return UITableViewCell() } } - -// MARK: - NCCell Delegates -extension NCShare: NCShareLinkCellDelegate, NCShareUserCellDelegate { - - func tapCopy(with tableShare: tableShare?, sender: Any) { - - if let link = tableShare?.url { - NCShareCommon.shared.copyLink(link: link, viewController: self, sender: sender) - } - } - - func tapMenu(with tableShare: tableShare?, sender: Any) { - - guard let tableShare = tableShare else { return } - - if tableShare.shareType == 3 { - let views = NCShareCommon.shared.openViewMenuShareLink(shareViewController: self, 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.shared.openViewMenuUser(shareViewController: self, tableShare: tableShare, metadata: metadata!) - shareUserMenuView = views.shareUserMenuView - shareMenuViewWindow = views.viewWindow - - let tap = UITapGestureRecognizer(target: self, action: #selector(tapLinkMenuViewWindow)) - tap.delegate = self - shareMenuViewWindow?.addGestureRecognizer(tap) - } - } - - func showProfile(with tableShare: tableShare?, sender: Any) { - guard let tableShare = tableShare else { return } - showProfileMenu(userId: tableShare.shareWith) - } - - func quickStatus(with tableShare: tableShare?, sender: Any) { - - guard let tableShare = tableShare else { return } - - if tableShare.shareType != NCGlobal.shared.permissionDefaultFileRemoteShareNoSupportShareOption { - - let quickStatusMenu = NCShareQuickStatusMenu() - quickStatusMenu.toggleMenu(viewController: self, directory: metadata!.directory, tableShare: tableShare) - } - } -} diff --git a/iOSClient/Share/NCShareCommentsCell.swift b/iOSClient/Share/NCShareCommentsCell.swift index 36a31aae7..77335907b 100644 --- a/iOSClient/Share/NCShareCommentsCell.swift +++ b/iOSClient/Share/NCShareCommentsCell.swift @@ -38,24 +38,16 @@ class NCShareCommentsCell: UITableViewCell, NCCellProtocol { weak var delegate: NCShareCommentsCellDelegate? var filePreviewImageView: UIImageView? { - get { - return nil - } + return nil } var fileAvatarImageView: UIImageView? { - get { - return imageItem - } + return imageItem } var fileObjectId: String? { - get { - return nil - } + return nil } var fileUser: String? { - get { - return tableComments?.actorId - } + return tableComments?.actorId } override func awakeFromNib() { diff --git a/iOSClient/Share/NCShareCommon.swift b/iOSClient/Share/NCShareCommon.swift index 54ad9d29d..024f4356d 100644 --- a/iOSClient/Share/NCShareCommon.swift +++ b/iOSClient/Share/NCShareCommon.swift @@ -45,7 +45,7 @@ class NCShareCommon: NSObject { let size: CGFloat = 200 - let bottomImage = UIImage(named: "circle.fill")!.image(color: colorCircle, size: size/2) + let bottomImage = UIImage(named: "circle_fill")!.image(color: colorCircle, size: size/2) let topImage = UIImage(named: imageName)!.image(color: .white, size: size/2) UIGraphicsBeginImageContextWithOptions(CGSize(width: size, height: size), false, UIScreen.main.scale) bottomImage.draw(in: CGRect(origin: CGPoint.zero, size: CGSize(width: size, height: size))) @@ -56,126 +56,6 @@ class NCShareCommon: NSObject { return image } - func openViewMenuShareLink(shareViewController: NCShare, tableShare: tableShare?, metadata: tableMetadata) -> (shareLinkMenuView: NCShareLinkMenuView, viewWindow: UIView) { - - var shareLinkMenuView: NCShareLinkMenuView - let window = UIApplication.shared.keyWindow! - let viewWindow = UIView(frame: window.bounds) - - window.addSubview(viewWindow) - viewWindow.autoresizingMask = [.flexibleWidth, .flexibleHeight] - - if metadata.directory { - shareLinkMenuView = Bundle.main.loadNibNamed("NCShareLinkFolderMenuView", owner: self, options: nil)?.first as! NCShareLinkMenuView - } else { - shareLinkMenuView = Bundle.main.loadNibNamed("NCShareLinkMenuView", owner: self, options: nil)?.first as! NCShareLinkMenuView - } - - shareLinkMenuView.width = 250 - if metadata.directory { - shareLinkMenuView.height = 600 - } else { - shareLinkMenuView.height = 500 - } - - shareLinkMenuView.backgroundColor = NCBrandColor.shared.systemBackground - shareLinkMenuView.metadata = metadata - shareLinkMenuView.viewWindow = viewWindow - shareLinkMenuView.shareViewController = shareViewController - shareLinkMenuView.reloadData(idShare: tableShare?.idShare ?? 0) - shareLinkMenuView.translatesAutoresizingMaskIntoConstraints = false - viewWindow.addSubview(shareLinkMenuView) - - NSLayoutConstraint.activate([ - shareLinkMenuView.widthAnchor.constraint(equalToConstant: shareLinkMenuView.width), - shareLinkMenuView.heightAnchor.constraint(equalToConstant: shareLinkMenuView.height), - shareLinkMenuView.centerXAnchor.constraint(equalTo: viewWindow.centerXAnchor), - shareLinkMenuView.centerYAnchor.constraint(equalTo: viewWindow.centerYAnchor) - ]) - - return(shareLinkMenuView: shareLinkMenuView, viewWindow: viewWindow) - } - - func openViewMenuUser(shareViewController: NCShare, tableShare: tableShare?, metadata: tableMetadata) -> (shareUserMenuView: NCShareUserMenuView, viewWindow: UIView) { - - var shareUserMenuView: NCShareUserMenuView - let window = UIApplication.shared.keyWindow! - let viewWindow = UIView(frame: window.bounds) - - window.addSubview(viewWindow) - viewWindow.autoresizingMask = [.flexibleWidth, .flexibleHeight] - - if metadata.directory { - shareUserMenuView = Bundle.main.loadNibNamed("NCShareUserFolderMenuView", owner: self, options: nil)?.first as! NCShareUserMenuView - } else { - shareUserMenuView = Bundle.main.loadNibNamed("NCShareUserMenuView", owner: self, options: nil)?.first as! NCShareUserMenuView - } - - shareUserMenuView.width = 250 - if metadata.directory { - shareUserMenuView.height = 420 - } else { - shareUserMenuView.height = 270 - } - - shareUserMenuView.backgroundColor = NCBrandColor.shared.systemBackground - shareUserMenuView.metadata = metadata - shareUserMenuView.viewWindow = viewWindow - shareUserMenuView.shareViewController = shareViewController - shareUserMenuView.reloadData(idShare: tableShare?.idShare ?? 0) - shareUserMenuView.translatesAutoresizingMaskIntoConstraints = false - viewWindow.addSubview(shareUserMenuView) - - NSLayoutConstraint.activate([ - shareUserMenuView.widthAnchor.constraint(equalToConstant: shareUserMenuView.width), - shareUserMenuView.heightAnchor.constraint(equalToConstant: shareUserMenuView.height), - shareUserMenuView.centerXAnchor.constraint(equalTo: viewWindow.centerXAnchor), - shareUserMenuView.centerYAnchor.constraint(equalTo: viewWindow.centerYAnchor) - ]) - - 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 + 10, width: width - 20, height: 300)) - - if #available(iOS 13.0, *) { - calendar.appearance.headerTitleColor = .label - } else { - calendar.appearance.headerTitleColor = .black - } - calendar.backgroundColor = NCBrandColor.shared.systemBackground - 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.headerTitleFont = UIFont.systemFont(ofSize: 13) - - calendar.appearance.weekdayTextColor = NCBrandColor.shared.gray - calendar.appearance.weekdayFont = UIFont.systemFont(ofSize: 13) - - calendar.appearance.todayColor = NCBrandColor.shared.brandElement - calendar.appearance.titleFont = UIFont.systemFont(ofSize: 13) - - viewWindow.addSubview(calendar) - - return(calendarView: calendar, viewWindow: viewWindow) - } - func copyLink(link: String, viewController: UIViewController, sender: Any) { let objectsToShare = [link] @@ -187,8 +67,9 @@ class NCShareCommon: NSObject { activityViewController.popoverPresentationController?.sourceRect = (sender as AnyObject).bounds } } - - viewController.present(activityViewController, animated: true, completion: nil) + DispatchQueue.main.async { + viewController.present(activityViewController, animated: true, completion: nil) + } } func getImageShareType(shareType: Int) -> UIImage? { diff --git a/iOSClient/Share/NCShareHeaderView.xib b/iOSClient/Share/NCShareHeaderView.xib index 82e614d86..841623f6a 100644 --- a/iOSClient/Share/NCShareHeaderView.xib +++ b/iOSClient/Share/NCShareHeaderView.xib @@ -1,27 +1,26 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19162" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES"> - <device id="retina4_0" orientation="portrait" appearance="light"/> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES"> + <device id="retina4_0" orientation="landscape" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19144"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/> <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 contentMode="scaleToFill" id="iN0-l3-epB" customClass="NCShareHeaderView" customModule="Nextcloud" customModuleProvider="target"> - <rect key="frame" x="0.0" y="0.0" width="320" height="568"/> + <rect key="frame" x="0.0" y="0.0" width="474" height="100"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="79H-PA-1m2"> - <rect key="frame" x="100" y="70" width="120" height="120"/> + <rect key="frame" x="20" y="0.0" width="100" height="100"/> <constraints> - <constraint firstAttribute="height" constant="120" id="Imw-QI-Org"/> - <constraint firstAttribute="width" constant="120" id="YKb-24-fln"/> + <constraint firstAttribute="width" secondItem="79H-PA-1m2" secondAttribute="height" id="kPd-Ha-PKN"/> </constraints> </imageView> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="headTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="n1G-pn-D8s" customClass="MarqueeLabel" customModule="MarqueeLabel"> - <rect key="frame" x="15" y="520" width="290" height="18"/> + <rect key="frame" x="128" y="8" width="326" height="18"/> <fontDescription key="fontDescription" type="system" pointSize="15"/> <nil key="textColor"/> <nil key="highlightedColor"/> @@ -29,43 +28,44 @@ <userDefinedRuntimeAttribute type="boolean" keyPath="tapToScroll" value="YES"/> </userDefinedRuntimeAttributes> </label> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bOQ-tC-40T"> - <rect key="frame" x="40" y="543" width="265" height="15"/> - <fontDescription key="fontDescription" type="system" pointSize="12"/> - <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/> - <nil key="highlightedColor"/> - </label> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EaW-fI-EmD"> - <rect key="frame" x="15" y="542" width="15" height="15"/> + <rect key="frame" x="128" y="77" width="15" height="15"/> <constraints> - <constraint firstAttribute="height" constant="15" id="Rli-bh-8fJ"/> - <constraint firstAttribute="width" constant="15" id="cU5-4t-7Qf"/> + <constraint firstAttribute="width" constant="15" id="GQs-ak-G4R"/> + <constraint firstAttribute="height" constant="15" id="gFH-uD-FZ0"/> </constraints> - <state key="normal" image="favorite"/> + <state key="normal" image="star.fill"/> <connections> <action selector="touchUpInsideFavorite:" destination="iN0-l3-epB" eventType="touchUpInside" id="r4F-nS-R08"/> </connections> </button> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bOQ-tC-40T"> + <rect key="frame" x="148" y="77" width="31" height="15"/> + <fontDescription key="fontDescription" type="system" pointSize="12"/> + <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/> + <nil key="highlightedColor"/> + </label> </subviews> <constraints> - <constraint firstItem="EaW-fI-EmD" firstAttribute="top" secondItem="n1G-pn-D8s" secondAttribute="bottom" constant="4" id="8Jc-BA-mYt"/> - <constraint firstItem="bOQ-tC-40T" firstAttribute="top" secondItem="n1G-pn-D8s" secondAttribute="bottom" constant="5" id="IRS-qU-ubd"/> - <constraint firstAttribute="bottom" secondItem="bOQ-tC-40T" secondAttribute="bottom" constant="10" id="KvA-Oh-KeQ"/> - <constraint firstAttribute="trailing" secondItem="bOQ-tC-40T" secondAttribute="trailing" constant="15" id="LAA-Eb-HZj"/> - <constraint firstItem="n1G-pn-D8s" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="15" id="cpD-9L-mBy"/> - <constraint firstAttribute="trailing" secondItem="n1G-pn-D8s" secondAttribute="trailing" constant="15" id="g7A-jG-74Q"/> - <constraint firstItem="79H-PA-1m2" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="70" id="k8q-dk-ofe"/> - <constraint firstItem="EaW-fI-EmD" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="15" id="oRc-nv-VzO"/> - <constraint firstItem="79H-PA-1m2" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="t10-qd-7Cn"/> - <constraint firstItem="bOQ-tC-40T" firstAttribute="leading" secondItem="EaW-fI-EmD" secondAttribute="trailing" constant="10" id="uf6-8A-fN4"/> + <constraint firstAttribute="trailing" secondItem="n1G-pn-D8s" secondAttribute="trailing" constant="20" id="0ss-6p-laS"/> + <constraint firstItem="EaW-fI-EmD" firstAttribute="leading" secondItem="79H-PA-1m2" secondAttribute="trailing" constant="8" symbolic="YES" id="7jw-Bt-GHm"/> + <constraint firstItem="bOQ-tC-40T" firstAttribute="leading" secondItem="EaW-fI-EmD" secondAttribute="trailing" constant="5" id="HNe-K2-JNt"/> + <constraint firstAttribute="bottom" secondItem="bOQ-tC-40T" secondAttribute="bottom" constant="8" id="LkB-ps-xwS"/> + <constraint firstItem="n1G-pn-D8s" firstAttribute="leading" secondItem="79H-PA-1m2" secondAttribute="trailing" constant="8" symbolic="YES" id="ca1-QS-7XL"/> + <constraint firstItem="EaW-fI-EmD" firstAttribute="centerY" secondItem="bOQ-tC-40T" secondAttribute="centerY" id="g7i-UL-F1V"/> + <constraint firstItem="n1G-pn-D8s" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="8" id="gf7-1r-fAJ"/> + <constraint firstItem="79H-PA-1m2" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="pxE-GL-Wu8"/> + <constraint firstItem="79H-PA-1m2" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="sPO-Xj-c1R"/> + <constraint firstAttribute="bottom" secondItem="79H-PA-1m2" secondAttribute="bottom" id="yMh-bh-mR7"/> </constraints> + <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> <connections> <outlet property="favorite" destination="EaW-fI-EmD" id="dv5-Qo-tPx"/> <outlet property="imageView" destination="79H-PA-1m2" id="t6m-wr-OQ5"/> <outlet property="info" destination="bOQ-tC-40T" id="N7R-YH-Xek"/> <outlet property="path" destination="n1G-pn-D8s" id="ckb-qc-lqb"/> </connections> - <point key="canvasLocation" x="38" y="253"/> + <point key="canvasLocation" x="-12.67605633802817" y="45"/> </view> </objects> <designables> @@ -74,6 +74,6 @@ </designable> </designables> <resources> - <image name="favorite" width="300" height="300"/> + <image name="star.fill" width="512" height="512"/> </resources> </document> diff --git a/iOSClient/Share/NCShareLinkCell.swift b/iOSClient/Share/NCShareLinkCell.swift index 7468b78ba..d24f1536e 100644 --- a/iOSClient/Share/NCShareLinkCell.swift +++ b/iOSClient/Share/NCShareLinkCell.swift @@ -24,29 +24,62 @@ import UIKit class NCShareLinkCell: UITableViewCell { - @IBOutlet weak var imageItem: UIImageView! - @IBOutlet weak var labelTitle: UILabel! - @IBOutlet weak var buttonCopy: UIButton! - @IBOutlet weak var buttonMenu: UIButton! - - private let iconShare: CGFloat = 200 + @IBOutlet private weak var imageItem: UIImageView! + @IBOutlet private weak var labelTitle: UILabel! + @IBOutlet private weak var descriptionLabel: UILabel! + @IBOutlet private weak var menuButton: UIButton! + @IBOutlet private weak var copyButton: UIButton! var tableShare: tableShare? weak var delegate: NCShareLinkCellDelegate? + var isInternalLink = false + + override func prepareForReuse() { + super.prepareForReuse() + isInternalLink = false + tableShare = nil + } + + func setupCellUI() { + var imageName: String + var imageBGColor: UIColor + var menuImageName = "shareMenu" + + menuButton.isHidden = isInternalLink + descriptionLabel.isHidden = !isInternalLink + copyButton.isHidden = !isInternalLink && tableShare == nil + + if isInternalLink { + imageName = "shareInternalLink" + imageBGColor = .gray + labelTitle.text = NSLocalizedString("_share_internal_link_", comment: "") + descriptionLabel.text = NSLocalizedString("_share_internal_link_des_", comment: "") + } else { + labelTitle.text = NSLocalizedString("_share_link_", comment: "") + if let tableShare = tableShare { + if !tableShare.label.isEmpty { + labelTitle.text? += " (\(tableShare.label))" + } + } else { + menuImageName = "shareAdd" + } + + imageName = "sharebylink" + imageBGColor = NCBrandColor.shared.brandElement - override func awakeFromNib() { - super.awakeFromNib() + menuButton.setImage(UIImage(named: menuImageName)?.image(color: .gray, size: 50), for: .normal) + } - imageItem.image = NCShareCommon.shared.createLinkAvatar(imageName: "sharebylink", colorCircle: NCBrandColor.shared.brandElement) - buttonCopy.setImage(UIImage(named: "shareCopy")!.image(color: .gray, size: 50), for: .normal) - buttonMenu.setImage(UIImage(named: "shareMenu")!.image(color: .gray, size: 50), for: .normal) + labelTitle.textColor = NCBrandColor.shared.label + imageItem.image = NCShareCommon.shared.createLinkAvatar(imageName: imageName, colorCircle: imageBGColor) + copyButton.setImage(UIImage(named: "shareCopy")?.image(color: .gray, size: 50), for: .normal) } - @IBAction func touchUpInsideCopy(_ sender: Any) { + @IBAction func touchUpCopy(_ sender: Any) { delegate?.tapCopy(with: tableShare, sender: sender) } - @IBAction func touchUpInsideMenu(_ sender: Any) { + @IBAction func touchUpMenu(_ sender: Any) { delegate?.tapMenu(with: tableShare, sender: sender) } } diff --git a/iOSClient/Share/NCShareLinkCell.xib b/iOSClient/Share/NCShareLinkCell.xib index 81ba5aa18..b5172d16f 100755 --- a/iOSClient/Share/NCShareLinkCell.xib +++ b/iOSClient/Share/NCShareLinkCell.xib @@ -1,11 +1,10 @@ <?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" useSafeAreas="YES" colorMatched="YES"> - <device id="retina4_7" orientation="portrait"> - <adaptation id="fullscreen"/> - </device> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> + <device id="retina4_7" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/> + <capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <objects> @@ -15,7 +14,7 @@ <rect key="frame" x="0.0" y="0.0" width="600" height="90"/> <autoresizingMask key="autoresizingMask"/> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="qJF-Yc-gKE" id="3Oe-gU-3Nk"> - <rect key="frame" x="0.0" y="0.0" width="600" height="89.5"/> + <rect key="frame" x="0.0" y="0.0" width="600" height="90"/> <autoresizingMask key="autoresizingMask"/> <subviews> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" image="circle" translatesAutoresizingMaskIntoConstraints="NO" id="qDs-UG-Mn7" userLabel="ImageItem"> @@ -25,63 +24,84 @@ <constraint firstAttribute="width" constant="40" id="GNY-Va-SIJ"/> </constraints> </imageView> - <label opaque="NO" userInteractionEnabled="NO" tag="101" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Share link" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="otH-mT-7Z4" userLabel="labelTitle"> - <rect key="frame" x="55" y="36" width="150" height="18"/> - <constraints> - <constraint firstAttribute="width" constant="150" id="4Oa-yZ-HZK"/> - <constraint firstAttribute="height" constant="18" id="iet-xr-SX6"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="15"/> - <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> - <nil key="highlightedColor"/> - </label> - <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="xaz-vY-Jzu" userLabel="ButtonCopy"> - <rect key="frame" x="520" y="35" width="20" height="20"/> - <constraints> - <constraint firstAttribute="width" constant="20" id="0JR-eM-oir"/> - <constraint firstAttribute="height" constant="20" id="HVo-ht-9m6"/> - </constraints> - <state key="normal" image="shareCopy"/> - <connections> - <action selector="touchUpInsideCopy:" destination="qJF-Yc-gKE" eventType="touchUpInside" id="hSV-RK-FAe"/> - </connections> - </button> - <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="J1z-RG-U4A" userLabel="ButtonMenu"> - <rect key="frame" x="570" y="35" width="20" height="20"/> - <constraints> - <constraint firstAttribute="height" constant="20" id="G48-LB-BsD"/> - <constraint firstAttribute="width" constant="20" id="vLI-cJ-Jqx"/> - </constraints> - <state key="normal" image="shareMenu"/> - <connections> - <action selector="touchUpInsideMenu:" destination="qJF-Yc-gKE" eventType="touchUpInside" id="GT2-Ef-FfR"/> - </connections> - </button> + <stackView opaque="NO" contentMode="scaleToFill" spacing="30" translatesAutoresizingMaskIntoConstraints="NO" id="OQv-Vf-bvD"> + <rect key="frame" x="520" y="35" width="70" height="20"/> + <subviews> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="xaz-vY-Jzu" userLabel="ButtonCopy"> + <rect key="frame" x="0.0" y="0.0" width="20" height="20"/> + <constraints> + <constraint firstAttribute="width" constant="20" id="0JR-eM-oir"/> + <constraint firstAttribute="height" constant="20" id="HVo-ht-9m6"/> + </constraints> + <state key="normal" image="shareCopy"/> + <connections> + <action selector="touchUpCopy:" destination="qJF-Yc-gKE" eventType="touchUpInside" id="s3f-6n-cKF"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="J1z-RG-U4A" userLabel="ButtonMenu"> + <rect key="frame" x="50" y="0.0" width="20" height="20"/> + <constraints> + <constraint firstAttribute="height" constant="20" id="G48-LB-BsD"/> + <constraint firstAttribute="width" constant="20" id="vLI-cJ-Jqx"/> + </constraints> + <state key="normal" image="shareMenu"/> + <connections> + <action selector="touchUpMenu:" destination="qJF-Yc-gKE" eventType="touchUpInside" id="hFx-Ib-xay"/> + </connections> + </button> + </subviews> + </stackView> + <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="Wxr-1B-Czy"> + <rect key="frame" x="53" y="12" width="452" height="66"/> + <subviews> + <label opaque="NO" userInteractionEnabled="NO" tag="101" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Share link" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="otH-mT-7Z4" userLabel="labelTitle"> + <rect key="frame" x="0.0" y="0.0" width="452" height="22"/> + <fontDescription key="fontDescription" type="system" pointSize="15"/> + <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> + <nil key="highlightedColor"/> + </label> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalCompressionResistancePriority="245" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WJj-9P-3bn"> + <rect key="frame" x="0.0" y="26" width="452" height="40"/> + <constraints> + <constraint firstAttribute="height" constant="40" id="Eo4-Rq-ETK"/> + </constraints> + <string key="text">Only works.... +.;...</string> + <fontDescription key="fontDescription" type="system" pointSize="13"/> + <color key="textColor" systemColor="secondaryLabelColor"/> + <nil key="highlightedColor"/> + </label> + </subviews> + </stackView> </subviews> <constraints> - <constraint firstItem="otH-mT-7Z4" firstAttribute="leading" secondItem="qDs-UG-Mn7" secondAttribute="trailing" constant="10" id="7o5-Rj-6lV"/> - <constraint firstItem="otH-mT-7Z4" firstAttribute="centerY" secondItem="3Oe-gU-3Nk" secondAttribute="centerY" id="JNE-HJ-E36"/> + <constraint firstItem="OQv-Vf-bvD" firstAttribute="leading" secondItem="Wxr-1B-Czy" secondAttribute="trailing" constant="15" id="8QW-n0-4lO"/> <constraint firstItem="qDs-UG-Mn7" firstAttribute="leading" secondItem="3Oe-gU-3Nk" secondAttribute="leading" constant="5" id="KOm-wo-CBa"/> - <constraint firstItem="J1z-RG-U4A" firstAttribute="centerY" secondItem="3Oe-gU-3Nk" secondAttribute="centerY" id="TvQ-yn-L5w"/> + <constraint firstAttribute="bottom" secondItem="Wxr-1B-Czy" secondAttribute="bottom" constant="12" id="MM0-9i-BpF"/> + <constraint firstAttribute="trailing" secondItem="OQv-Vf-bvD" secondAttribute="trailing" constant="10" id="W3b-ww-vbQ"/> <constraint firstItem="qDs-UG-Mn7" firstAttribute="centerY" secondItem="3Oe-gU-3Nk" secondAttribute="centerY" id="ZrD-Aw-xkx"/> - <constraint firstItem="J1z-RG-U4A" firstAttribute="leading" secondItem="xaz-vY-Jzu" secondAttribute="trailing" constant="30" id="gGI-DA-dwq"/> - <constraint firstItem="xaz-vY-Jzu" firstAttribute="centerY" secondItem="3Oe-gU-3Nk" secondAttribute="centerY" id="o6o-Zj-1aU"/> - <constraint firstAttribute="trailing" secondItem="J1z-RG-U4A" secondAttribute="trailing" constant="10" id="pQA-B9-MM5"/> + <constraint firstItem="OQv-Vf-bvD" firstAttribute="centerY" secondItem="3Oe-gU-3Nk" secondAttribute="centerY" id="eLc-gk-xAr"/> + <constraint firstItem="Wxr-1B-Czy" firstAttribute="leading" secondItem="qDs-UG-Mn7" secondAttribute="trailing" constant="8" id="nXI-b3-EJM"/> + <constraint firstItem="Wxr-1B-Czy" firstAttribute="top" secondItem="3Oe-gU-3Nk" secondAttribute="top" constant="12" id="vxe-9X-O1f"/> </constraints> </tableViewCellContentView> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <connections> - <outlet property="buttonCopy" destination="xaz-vY-Jzu" id="WVv-oI-jD8"/> - <outlet property="buttonMenu" destination="J1z-RG-U4A" id="L2V-Ev-Cx0"/> + <outlet property="copyButton" destination="xaz-vY-Jzu" id="pMt-Zu-ORX"/> + <outlet property="descriptionLabel" destination="WJj-9P-3bn" id="QC7-SX-O3M"/> <outlet property="imageItem" destination="qDs-UG-Mn7" id="jxL-r7-BVs"/> <outlet property="labelTitle" destination="otH-mT-7Z4" id="f9z-Oa-OiR"/> + <outlet property="menuButton" destination="J1z-RG-U4A" id="VCC-y1-LRK"/> </connections> <point key="canvasLocation" x="97.599999999999994" y="276.1619190404798"/> </tableViewCell> </objects> <resources> - <image name="circle" width="329" height="329"/> + <image name="circle" width="210" height="156"/> <image name="shareCopy" width="329" height="329"/> <image name="shareMenu" width="329" height="329"/> + <systemColor name="secondaryLabelColor"> + <color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/> + </systemColor> </resources> </document> diff --git a/iOSClient/Share/NCShareLinkFolderMenuView.xib b/iOSClient/Share/NCShareLinkFolderMenuView.xib deleted file mode 100644 index 8fb3aed5c..000000000 --- a/iOSClient/Share/NCShareLinkFolderMenuView.xib +++ /dev/null @@ -1,318 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES"> - <device id="retina4_0" orientation="portrait" appearance="light"/> - <dependencies> - <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/> - <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="NCShareLinkMenuView" customModule="Nextcloud" customModuleProvider="target"> - <rect key="frame" x="0.0" y="0.0" width="250" height="600"/> - <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" userLabel="SwitchAllowEditing"> - <rect key="frame" x="10" y="62" width="51" height="31"/> - <connections> - <action selector="switchReadOnlyWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="IZJ-Hz-NxB"/> - </connections> - </switch> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Read only" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IHP-P8-rm2"> - <rect key="frame" x="70" y="70" width="170" 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="UIn-eq-hkP"> - <rect key="frame" x="10" y="215" width="51" height="31"/> - <connections> - <action selector="switchHideDownloadChangedWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="ZUj-2h-gQC"/> - </connections> - </switch> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Hide download" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KXo-cP-gkc"> - <rect key="frame" x="70" y="223" width="170" height="15"/> - <constraints> - <constraint firstAttribute="height" constant="15" id="IEP-cO-Um6"/> - </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="HDO-WC-RvJ"> - <rect key="frame" x="10" y="266" width="51" height="31"/> - <connections> - <action selector="switchPasswordProtectChangedWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="wGL-du-81Q"/> - </connections> - </switch> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Password protect" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HaY-OM-mQh"> - <rect key="frame" x="70" y="274" width="170" height="15"/> - <constraints> - <constraint firstAttribute="height" constant="15" id="MeH-bs-tZK"/> - </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="e1F-PV-32s"> - <rect key="frame" x="70" y="299" width="170" height="30"/> - <constraints> - <constraint firstAttribute="height" constant="30" id="tTv-8w-kxm"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="13"/> - <textInputTraits key="textInputTraits" secureTextEntry="YES" textContentType="password"/> - <connections> - <action selector="fieldPasswordProtectDidEndOnExitWithTextField:" destination="iN0-l3-epB" eventType="editingDidEndOnExit" id="2PO-wf-bHs"/> - </connections> - </textField> - <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="349" width="51" height="31"/> - <connections> - <action selector="switchSetExpirationDateWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="26x-ld-Jsj"/> - </connections> - </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="357" width="170" 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="382" width="170" height="30"/> - <constraints> - <constraint firstAttribute="height" constant="30" id="G4f-LN-v7k"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="13"/> - <textInputTraits key="textInputTraits"/> - <connections> - <action selector="fieldSetExpirationDateWithSender:" destination="iN0-l3-epB" eventType="editingDidBegin" id="5Ou-k5-UM5"/> - </connections> - </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="432" 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="437" width="175" 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="462" width="170" height="30"/> - <constraints> - <constraint firstAttribute="height" constant="30" id="2CZ-EP-NrP"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="13"/> - <textInputTraits key="textInputTraits"/> - <connections> - <action selector="fieldNoteToRecipientDidEndOnExitWithTextField:" destination="iN0-l3-epB" eventType="editingDidEndOnExit" id="Z9v-qs-dp4"/> - </connections> - </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="512" 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="Delete share link" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ff4-JE-zGU"> - <rect key="frame" x="70" y="517" width="170" 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="512" width="217" height="25"/> - <constraints> - <constraint firstAttribute="height" constant="25" id="fWP-XF-kQx"/> - </constraints> - <connections> - <action selector="buttonDeleteShareLinkWithSender:" destination="iN0-l3-epB" eventType="touchUpInside" id="ANe-oV-NCX"/> - </connections> - </button> - <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="add" translatesAutoresizingMaskIntoConstraints="NO" id="6SU-Ak-Q7m"> - <rect key="frame" x="13" y="557" width="25" height="25"/> - <constraints> - <constraint firstAttribute="width" constant="25" id="NLr-qc-w3G"/> - <constraint firstAttribute="height" constant="25" id="wkp-ks-jJM"/> - </constraints> - </imageView> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Add another link" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cna-iK-PD7"> - <rect key="frame" x="70" y="562" width="170" height="15"/> - <constraints> - <constraint firstAttribute="height" constant="15" id="p9o-oI-gWq"/> - </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="0bK-Kl-hcs"> - <rect key="frame" x="13" y="557" width="217" height="25"/> - <constraints> - <constraint firstAttribute="height" constant="25" id="wQO-6d-vWV"/> - </constraints> - <connections> - <action selector="buttonAddAnotherLinkWithSender:" destination="iN0-l3-epB" eventType="touchUpInside" id="1Ea-g9-pQ8"/> - </connections> - </button> - <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="0ON-8M-J6K" userLabel="SwitchAllowEditing"> - <rect key="frame" x="10" y="113" width="51" height="31"/> - <connections> - <action selector="switchAllowUploadAndEditingWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="HEh-km-e1I"/> - </connections> - </switch> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Allow upload and editing" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9rD-k5-hnW"> - <rect key="frame" x="70" y="121" width="170" height="15"/> - <constraints> - <constraint firstAttribute="height" constant="15" id="zKi-d5-7DQ"/> - </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="jpY-MU-ecU" userLabel="SwitchAllowEditing"> - <rect key="frame" x="10" y="164" width="51" height="31"/> - <connections> - <action selector="switchFileDropWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="32M-Ks-mr6"/> - </connections> - </switch> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="File drop (upload only)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QJc-Cx-Fa3"> - <rect key="frame" x="70" y="172" width="170" height="15"/> - <constraints> - <constraint firstAttribute="height" constant="15" id="GRe-k0-V9C"/> - </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" placeholder="Placeholder" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="JOx-l5-TUp"> - <rect key="frame" x="10" y="12" width="230" height="30"/> - <constraints> - <constraint firstAttribute="height" constant="30" id="eTg-X2-ih2"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="13"/> - <textInputTraits key="textInputTraits"/> - <connections> - <action selector="fielLabelDidEndOnExitWithTextField:" destination="iN0-l3-epB" eventType="editingDidEndOnExit" id="s4f-hL-eZ2"/> - </connections> - </textField> - </subviews> - <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="HaY-OM-mQh" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="4CZ-Mo-lOP"/> - <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 firstItem="0ON-8M-J6K" firstAttribute="top" secondItem="sjf-wF-y07" secondAttribute="bottom" constant="20" id="AGy-qr-ahT"/> - <constraint firstItem="0bK-Kl-hcs" firstAttribute="top" secondItem="CLA-UL-mYb" secondAttribute="bottom" constant="20" id="Bka-Hj-Arm"/> - <constraint firstAttribute="trailing" secondItem="ymk-0u-ddH" secondAttribute="trailing" constant="10" id="Chd-iQ-EdR"/> - <constraint firstItem="KXo-cP-gkc" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="CuB-lc-pHi"/> - <constraint firstItem="UIn-eq-hkP" firstAttribute="top" secondItem="jpY-MU-ecU" secondAttribute="bottom" constant="20" id="EO5-Qr-Xxq"/> - <constraint firstItem="UIn-eq-hkP" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="FwN-Rj-koX"/> - <constraint firstItem="HDO-WC-RvJ" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="GTl-Tq-cLY"/> - <constraint firstItem="IHP-P8-rm2" firstAttribute="centerY" secondItem="sjf-wF-y07" secondAttribute="centerY" id="HiA-pE-L6l"/> - <constraint firstItem="6SU-Ak-Q7m" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="13" id="Hqf-wy-u3S"/> - <constraint firstAttribute="trailing" secondItem="e1F-PV-32s" secondAttribute="trailing" constant="10" id="ImT-sr-UAr"/> - <constraint firstAttribute="trailing" secondItem="QJc-Cx-Fa3" secondAttribute="trailing" constant="10" id="JJ4-N8-Sbc"/> - <constraint firstItem="QJc-Cx-Fa3" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="Jnb-0A-4RI"/> - <constraint firstAttribute="trailing" secondItem="0bK-Kl-hcs" secondAttribute="trailing" constant="20" id="Jy3-Qb-ucs"/> - <constraint firstAttribute="trailing" secondItem="cna-iK-PD7" secondAttribute="trailing" constant="10" id="LEz-3F-g5Q"/> - <constraint firstAttribute="trailing" secondItem="grT-sd-j7q" secondAttribute="trailing" constant="5" id="Nyn-RD-jTz"/> - <constraint firstItem="6SU-Ak-Q7m" firstAttribute="top" secondItem="CLA-UL-mYb" secondAttribute="bottom" constant="20" id="OU0-vG-YTq"/> - <constraint firstAttribute="trailing" secondItem="FyH-3p-EdC" secondAttribute="trailing" constant="10" id="RhU-wl-afT"/> - <constraint firstItem="jpY-MU-ecU" firstAttribute="top" secondItem="0ON-8M-J6K" secondAttribute="bottom" constant="20" id="STB-7n-YyT"/> - <constraint firstItem="KXo-cP-gkc" firstAttribute="centerY" secondItem="UIn-eq-hkP" secondAttribute="centerY" id="Snt-zf-mcs"/> - <constraint firstItem="sjf-wF-y07" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="TFC-63-muN"/> - <constraint firstItem="dB8-1M-WZr" firstAttribute="top" secondItem="e1F-PV-32s" secondAttribute="bottom" constant="20" id="TIV-5L-Cza"/> - <constraint firstAttribute="trailing" secondItem="9rD-k5-hnW" secondAttribute="trailing" constant="10" id="TUb-mC-BhW"/> - <constraint firstItem="FyH-3p-EdC" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="TXe-jF-DdS"/> - <constraint firstItem="sjf-wF-y07" firstAttribute="top" secondItem="JOx-l5-TUp" secondAttribute="bottom" constant="20" id="UTk-iX-STG"/> - <constraint firstItem="dB8-1M-WZr" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="Ua2-93-05m"/> - <constraint firstItem="HaY-OM-mQh" firstAttribute="centerY" secondItem="HDO-WC-RvJ" secondAttribute="centerY" id="UcN-gf-Prv"/> - <constraint firstItem="e1F-PV-32s" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="YCZ-Z6-1Ty"/> - <constraint firstItem="9rD-k5-hnW" firstAttribute="centerY" secondItem="0ON-8M-J6K" secondAttribute="centerY" id="ZHV-C3-5rz"/> - <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="cna-iK-PD7" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="aZc-3Q-liP"/> - <constraint firstItem="F4T-wQ-tBU" firstAttribute="top" secondItem="ymk-0u-ddH" secondAttribute="bottom" constant="20" id="aj8-2w-ySe"/> - <constraint firstItem="0bK-Kl-hcs" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="13" id="bSd-GG-kS3"/> - <constraint firstItem="jpY-MU-ecU" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="bkE-q5-Vpr"/> - <constraint firstItem="HDO-WC-RvJ" firstAttribute="top" secondItem="UIn-eq-hkP" secondAttribute="bottom" constant="20" id="dex-mb-oRg"/> - <constraint firstItem="9rD-k5-hnW" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="eaN-ru-7yU"/> - <constraint firstItem="hr8-Qe-xD0" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="13" id="elF-be-kqS"/> - <constraint firstItem="cna-iK-PD7" firstAttribute="centerY" secondItem="0bK-Kl-hcs" secondAttribute="centerY" id="fDj-O7-Xdr"/> - <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 firstItem="e1F-PV-32s" firstAttribute="top" secondItem="HaY-OM-mQh" secondAttribute="bottom" constant="10" id="m5R-ms-HZh"/> - <constraint firstItem="0ON-8M-J6K" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="mQf-ph-p16"/> - <constraint firstAttribute="trailing" secondItem="JOx-l5-TUp" secondAttribute="trailing" constant="10" id="mq5-TO-THS"/> - <constraint firstItem="JOx-l5-TUp" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="12" id="n0G-KB-JE2"/> - <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="bottom" relation="greaterThanOrEqual" secondItem="0bK-Kl-hcs" secondAttribute="bottom" constant="10" id="rgb-gX-oJd"/> - <constraint firstAttribute="trailing" secondItem="KXo-cP-gkc" secondAttribute="trailing" constant="10" id="uDa-6r-K84"/> - <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 firstAttribute="trailing" secondItem="HaY-OM-mQh" secondAttribute="trailing" constant="10" id="yvI-xV-T7d"/> - <constraint firstItem="QJc-Cx-Fa3" firstAttribute="centerY" secondItem="jpY-MU-ecU" secondAttribute="centerY" id="z3L-Nd-uWl"/> - <constraint firstItem="Ff4-JE-zGU" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="zc7-db-OeN"/> - <constraint firstItem="JOx-l5-TUp" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="zsp-AH-Dzr"/> - </constraints> - <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> - <connections> - <outlet property="buttonAddAnotherLink" destination="0bK-Kl-hcs" id="XMo-Cp-y6f"/> - <outlet property="buttonDeleteShareLink" destination="CLA-UL-mYb" id="LVP-Vh-RHb"/> - <outlet property="fieldLabel" destination="JOx-l5-TUp" id="RTd-kU-zGz"/> - <outlet property="fieldNoteToRecipient" destination="FyH-3p-EdC" id="EBz-iA-1tq"/> - <outlet property="fieldPasswordProtect" destination="e1F-PV-32s" id="c1Y-0f-UYD"/> - <outlet property="fieldSetExpirationDate" destination="ymk-0u-ddH" id="W6o-xf-Zj2"/> - <outlet property="imageAddAnotherLink" destination="6SU-Ak-Q7m" id="Is7-q2-ZJu"/> - <outlet property="imageDeleteShareLink" destination="hr8-Qe-xD0" id="hGE-fg-rnv"/> - <outlet property="imageNoteToRecipient" destination="F4T-wQ-tBU" id="IHc-Q2-VxM"/> - <outlet property="labelAddAnotherLink" destination="cna-iK-PD7" id="xax-ip-GpR"/> - <outlet property="labelAllowUploadAndEditing" destination="9rD-k5-hnW" id="rqA-Me-ERg"/> - <outlet property="labelDeleteShareLink" destination="Ff4-JE-zGU" id="7jH-iS-zf8"/> - <outlet property="labelFileDrop" destination="QJc-Cx-Fa3" id="mN5-D6-JIs"/> - <outlet property="labelHideDownload" destination="KXo-cP-gkc" id="vis-Zu-pga"/> - <outlet property="labelNoteToRecipient" destination="grT-sd-j7q" id="yOv-Ke-EnF"/> - <outlet property="labelPasswordProtect" destination="HaY-OM-mQh" id="nlG-u7-v1H"/> - <outlet property="labelReadOnly" destination="IHP-P8-rm2" id="Rgw-5M-bf6"/> - <outlet property="labelSetExpirationDate" destination="qll-9F-4DA" id="K8B-Ys-V8e"/> - <outlet property="switchAllowUploadAndEditing" destination="0ON-8M-J6K" id="cY7-1g-kDC"/> - <outlet property="switchFileDrop" destination="jpY-MU-ecU" id="gs6-3e-de6"/> - <outlet property="switchHideDownload" destination="UIn-eq-hkP" id="25D-zI-MEj"/> - <outlet property="switchPasswordProtect" destination="HDO-WC-RvJ" id="K7a-3i-8kx"/> - <outlet property="switchReadOnly" destination="sjf-wF-y07" id="QSL-7L-cdn"/> - <outlet property="switchSetExpirationDate" destination="dB8-1M-WZr" id="R5d-Hf-ga6"/> - </connections> - <point key="canvasLocation" x="-142.5" y="519.71830985915494"/> - </view> - </objects> - <resources> - <image name="add" width="25" height="25"/> - <image name="file_txt" width="300" height="300"/> - <image name="trash" width="512" height="512"/> - </resources> -</document> diff --git a/iOSClient/Share/NCShareLinkMenuView.swift b/iOSClient/Share/NCShareLinkMenuView.swift deleted file mode 100644 index 19993dc42..000000000 --- a/iOSClient/Share/NCShareLinkMenuView.swift +++ /dev/null @@ -1,484 +0,0 @@ -// -// 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 UIKit -import FSCalendar -import NCCommunication - -class NCShareLinkMenuView: UIView, UIGestureRecognizerDelegate, UITextFieldDelegate, NCShareNetworkingDelegate, FSCalendarDelegate, FSCalendarDelegateAppearance { - - @IBOutlet weak var fieldLabel: UITextField! - - @IBOutlet weak var switchAllowEditing: UISwitch! - @IBOutlet weak var labelAllowEditing: UILabel! - - @IBOutlet weak var switchReadOnly: UISwitch! - @IBOutlet weak var labelReadOnly: UILabel! - - @IBOutlet weak var switchAllowUploadAndEditing: UISwitch! - @IBOutlet weak var labelAllowUploadAndEditing: UILabel! - - @IBOutlet weak var switchFileDrop: UISwitch! - @IBOutlet weak var labelFileDrop: 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 - - var width: CGFloat = 0 - var height: CGFloat = 0 - - private var tableShare: tableShare? - var metadata: tableMetadata? - var shareViewController: NCShare? - private var networking: NCShareNetworking? - - var viewWindow: UIView? - var viewWindowCalendar: UIView? - private var calendar: FSCalendar? - private var activeTextfieldDiff: CGFloat = 0 - private var activeTextField = UITextField() - - override func awakeFromNib() { - - 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 - - fieldLabel?.placeholder = NSLocalizedString("_Link_name_", comment: "") - - switchAllowEditing?.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) - switchAllowEditing?.onTintColor = NCBrandColor.shared.brandElement - switchReadOnly?.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) - switchReadOnly?.onTintColor = NCBrandColor.shared.brandElement - switchAllowUploadAndEditing?.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) - switchAllowUploadAndEditing?.onTintColor = NCBrandColor.shared.brandElement - switchFileDrop?.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) - switchFileDrop?.onTintColor = NCBrandColor.shared.brandElement - switchHideDownload.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) - switchHideDownload.onTintColor = NCBrandColor.shared.brandElement - switchPasswordProtect.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) - switchPasswordProtect.onTintColor = NCBrandColor.shared.brandElement - switchSetExpirationDate.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) - switchSetExpirationDate.onTintColor = NCBrandColor.shared.brandElement - - labelAllowEditing?.text = NSLocalizedString("_share_allow_editing_", comment: "") - labelAllowEditing?.textColor = NCBrandColor.shared.label - labelReadOnly?.text = NSLocalizedString("_share_read_only_", comment: "") - labelReadOnly?.textColor = NCBrandColor.shared.label - labelAllowUploadAndEditing?.text = NSLocalizedString("_share_allow_upload_", comment: "") - labelAllowUploadAndEditing?.textColor = NCBrandColor.shared.label - labelFileDrop?.text = NSLocalizedString("_share_file_drop_", comment: "") - labelFileDrop?.textColor = NCBrandColor.shared.label - labelHideDownload?.text = NSLocalizedString("_share_hide_download_", comment: "") - labelHideDownload?.textColor = NCBrandColor.shared.label - labelPasswordProtect?.text = NSLocalizedString("_share_password_protect_", comment: "") - labelPasswordProtect?.textColor = NCBrandColor.shared.label - labelSetExpirationDate?.text = NSLocalizedString("_share_expiration_date_", comment: "") - labelSetExpirationDate?.textColor = NCBrandColor.shared.label - labelNoteToRecipient?.text = NSLocalizedString("_share_note_recipient_", comment: "") - labelNoteToRecipient?.textColor = NCBrandColor.shared.label - labelDeleteShareLink?.text = NSLocalizedString("_share_delete_sharelink_", comment: "") - labelDeleteShareLink?.textColor = NCBrandColor.shared.label - labelAddAnotherLink?.text = NSLocalizedString("_share_add_sharelink_", comment: "") - labelAddAnotherLink?.textColor = NCBrandColor.shared.label - - fieldSetExpirationDate.inputView = UIView() - - fieldLabel.delegate = self - fieldPasswordProtect.delegate = self - fieldNoteToRecipient.delegate = self - - imageNoteToRecipient.image = UIImage(named: "file_txt")!.image(color: NCBrandColor.shared.gray, size: 50) - imageDeleteShareLink.image = NCUtility.shared.loadImage(named: "trash", color: NCBrandColor.shared.gray, size: 50) - imageAddAnotherLink.image = NCUtility.shared.loadImage(named: "plus", color: NCBrandColor.shared.gray, size: 50) - - NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) - } - - override func willMove(toWindow newWindow: UIWindow?) { - super.willMove(toWindow: newWindow) - - if newWindow == nil { - // UIView disappear - shareViewController?.reloadData() - } else { - // UIView appear - networking = NCShareNetworking(metadata: metadata!, urlBase: appDelegate.urlBase, view: self, delegate: self) - } - } - - func unLoad() { - viewWindowCalendar?.removeFromSuperview() - viewWindow?.removeFromSuperview() - - viewWindowCalendar = nil - viewWindow = nil - } - - func reloadData(idShare: Int) { - - guard let metadata = self.metadata else { return } - tableShare = NCManageDatabase.shared.getTableShare(account: metadata.account, idShare: idShare) - guard let tableShare = self.tableShare else { return } - - // Label - fieldLabel.text = tableShare.label - - if metadata.directory { - // File Drop - if tableShare.permissions == NCGlobal.shared.permissionCreateShare { - switchReadOnly.setOn(false, animated: false) - switchAllowUploadAndEditing.setOn(false, animated: false) - switchFileDrop.setOn(true, animated: false) - } else { - // Read Only - if CCUtility.isAnyPermission(toEdit: tableShare.permissions) { - switchReadOnly.setOn(false, animated: false) - switchAllowUploadAndEditing.setOn(true, animated: false) - } else { - switchReadOnly.setOn(true, animated: false) - switchAllowUploadAndEditing.setOn(false, animated: false) - } - switchFileDrop.setOn(false, animated: false) - } - } else { - // Allow editing - if CCUtility.isAnyPermission(toEdit: tableShare.permissions) { - switchAllowEditing.setOn(true, animated: false) - } else { - switchAllowEditing.setOn(false, animated: false) - } - } - - // Hide download - if tableShare.hideDownload { - switchHideDownload.setOn(true, animated: false) - } else { - switchHideDownload.setOn(false, animated: false) - } - - // Password protect - if 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.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 - fieldNoteToRecipient.text = tableShare.note - } - - func textFieldDidBeginEditing(_ textField: UITextField) { - - self.activeTextField = textField - } - - // MARK: - Keyboard notification - - @objc internal func keyboardWillShow(_ notification: Notification?) { - - activeTextfieldDiff = 0 - - if let info = notification?.userInfo, let centerObject = self.activeTextField.superview?.convert(self.activeTextField.center, to: nil) { - - let frameEndUserInfoKey = UIResponder.keyboardFrameEndUserInfoKey - if let keyboardFrame = info[frameEndUserInfoKey] as? CGRect { - let diff = keyboardFrame.origin.y - centerObject.y - self.activeTextField.frame.height - if diff < 0 { - activeTextfieldDiff = diff - self.frame.origin.y += diff - } - } - } - } - - @objc func keyboardWillHide(_ notification: Notification) { - self.frame.origin.y -= activeTextfieldDiff - } - - // MARK: - Tap viewWindowCalendar - - @objc func tapViewWindowCalendar(gesture: UITapGestureRecognizer) { - calendar?.removeFromSuperview() - viewWindowCalendar?.removeFromSuperview() - - calendar = nil - viewWindowCalendar = nil - - reloadData(idShare: tableShare?.idShare ?? 0) - } - - func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { - return gestureRecognizer.view == touch.view - } - - // MARK: - IBAction - - // Allow editing (file) - @IBAction func switchAllowEditingChanged(sender: UISwitch) { - - guard let tableShare = self.tableShare else { return } - guard let metadata = self.metadata else { return } - - var permissions: Int = 0 - - if sender.isOn { - permissions = CCUtility.getPermissionsValue(byCanEdit: true, andCanCreate: true, andCanChange: true, andCanDelete: true, andCanShare: false, andIsFolder: metadata.directory) - } else { - permissions = CCUtility.getPermissionsValue(byCanEdit: false, andCanCreate: false, andCanChange: false, andCanDelete: false, andCanShare: false, andIsFolder: metadata.directory) - } - - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: permissions, note: nil, label: nil, expirationDate: nil, hideDownload: tableShare.hideDownload) - } - - // Read Only (directory) - @IBAction func switchReadOnly(sender: UISwitch) { - - guard let tableShare = self.tableShare else { return } - guard let metadata = self.metadata else { return } - let permissions = CCUtility.getPermissionsValue(byCanEdit: false, andCanCreate: false, andCanChange: false, andCanDelete: false, andCanShare: false, andIsFolder: metadata.directory) - - if sender.isOn && permissions != tableShare.permissions { - switchAllowUploadAndEditing.setOn(false, animated: false) - switchFileDrop.setOn(false, animated: false) - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: permissions, note: nil, label: nil, expirationDate: nil, hideDownload: tableShare.hideDownload) - } else { - sender.setOn(true, animated: false) - } - } - - // Allow Upload And Editing (directory) - @IBAction func switchAllowUploadAndEditing(sender: UISwitch) { - - guard let tableShare = self.tableShare else { return } - guard let metadata = self.metadata else { return } - let permissions = CCUtility.getPermissionsValue(byCanEdit: true, andCanCreate: true, andCanChange: true, andCanDelete: true, andCanShare: false, andIsFolder: metadata.directory) - - if sender.isOn && permissions != tableShare.permissions { - switchReadOnly.setOn(false, animated: false) - switchFileDrop.setOn(false, animated: false) - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: permissions, note: nil, label: nil, expirationDate: nil, hideDownload: tableShare.hideDownload) - } else { - sender.setOn(true, animated: false) - } - } - - // File Drop (directory) - @IBAction func switchFileDrop(sender: UISwitch) { - - guard let tableShare = self.tableShare else { return } - let permissions = NCGlobal.shared.permissionCreateShare - - if sender.isOn && permissions != tableShare.permissions { - switchReadOnly.setOn(false, animated: false) - switchAllowUploadAndEditing.setOn(false, animated: false) - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: permissions, note: nil, label: nil, expirationDate: nil, hideDownload: tableShare.hideDownload) - } else { - sender.setOn(true, animated: false) - } - } - - // Hide download - @IBAction func switchHideDownloadChanged(sender: UISwitch) { - - guard let tableShare = self.tableShare else { return } - - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: tableShare.permissions, note: nil, label: nil, expirationDate: 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 { - networking?.updateShare(idShare: tableShare.idShare, password: "", permissions: tableShare.permissions, note: nil, label: nil, expirationDate: nil, hideDownload: tableShare.hideDownload) - } - } - - @IBAction func fieldPasswordProtectDidEndOnExit(textField: UITextField) { - - guard let tableShare = self.tableShare else { return } - - networking?.updateShare(idShare: tableShare.idShare, password: fieldPasswordProtect.text, permissions: tableShare.permissions, note: nil, label: nil, expirationDate: 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 { - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: tableShare.permissions, note: nil, label: nil, expirationDate: "", hideDownload: tableShare.hideDownload) - } - } - - @IBAction func fieldSetExpirationDate(sender: UITextField) { - - let calendar = NCShareCommon.shared.openCalendar(view: self, width: width, height: height) - calendar.calendarView.delegate = self - self.calendar = calendar.calendarView - viewWindowCalendar = calendar.viewWindow - - let tap = UITapGestureRecognizer(target: self, action: #selector(tapViewWindowCalendar)) - tap.delegate = self - viewWindowCalendar?.addGestureRecognizer(tap) - } - - // Note to recipient - @IBAction func fieldNoteToRecipientDidEndOnExit(textField: UITextField) { - - guard let tableShare = self.tableShare else { return } - if fieldNoteToRecipient.text == nil { return } - - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: tableShare.permissions, note: fieldNoteToRecipient.text, label: nil, expirationDate: nil, hideDownload: tableShare.hideDownload) - } - - // Label - @IBAction func fielLabelDidEndOnExit(textField: UITextField) { - - guard let tableShare = self.tableShare else { return } - if fieldLabel.text == nil { return } - - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: tableShare.permissions, note: nil, label: fieldLabel.text, expirationDate: nil, hideDownload: tableShare.hideDownload) - } - - // Delete share link - @IBAction func buttonDeleteShareLink(sender: UIButton) { - - guard let tableShare = self.tableShare else { return } - - networking?.unShare(idShare: tableShare.idShare) - } - - // Add another link - @IBAction func buttonAddAnotherLink(sender: UIButton) { - - networking?.createShareLink(password: "") - } - - // MARK: - Delegate networking - - func readShareCompleted() { - reloadData(idShare: tableShare?.idShare ?? 0) - } - - func shareCompleted() { - unLoad() - NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataNCShare) - } - - func unShareCompleted() { - unLoad() - NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataNCShare) - } - - func updateShareWithError(idShare: Int) { - reloadData(idShare: idShare) - } - - func getSharees(sharees: [NCCommunicationSharee]?) { } - - // MARK: - Delegate 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 } - - dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss" - let expirationDate = dateFormatter.string(from: date) - - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: tableShare.permissions, note: nil, label: nil, expirationDate: expirationDate, 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? { - return date > Date() ? NCBrandColor.shared.label : NCBrandColor.shared.systemGray3 - } -} diff --git a/iOSClient/Share/NCShareLinkMenuView.xib b/iOSClient/Share/NCShareLinkMenuView.xib deleted file mode 100644 index 35748f2e1..000000000 --- a/iOSClient/Share/NCShareLinkMenuView.xib +++ /dev/null @@ -1,274 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES"> - <device id="retina3_5" orientation="portrait" appearance="light"/> - <dependencies> - <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/> - <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="NCShareLinkMenuView" customModule="Nextcloud" customModuleProvider="target"> - <rect key="frame" x="0.0" y="0.0" width="250" height="500"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> - <subviews> - <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Placeholder" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="AjK-Ty-MRn"> - <rect key="frame" x="10" y="10" width="230" height="30"/> - <constraints> - <constraint firstAttribute="height" constant="30" id="sVl-pt-Qe5"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="13"/> - <textInputTraits key="textInputTraits"/> - <connections> - <action selector="fielLabelDidEndOnExitWithTextField:" destination="iN0-l3-epB" eventType="editingDidEndOnExit" id="WwX-ie-SRK"/> - </connections> - </textField> - <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="sjf-wF-y07" userLabel="SwitchAllowEditing"> - <rect key="frame" x="10" y="60" width="51" height="31"/> - <connections> - <action selector="switchAllowEditingChangedWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="22f-fh-Qc1"/> - </connections> - </switch> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Allow editing" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IHP-P8-rm2"> - <rect key="frame" x="70" y="68" width="170" 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="UIn-eq-hkP"> - <rect key="frame" x="10" y="111" width="51" height="31"/> - <connections> - <action selector="switchHideDownloadChangedWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="ZUj-2h-gQC"/> - </connections> - </switch> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Hide download" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KXo-cP-gkc"> - <rect key="frame" x="70" y="119" width="170" height="15"/> - <constraints> - <constraint firstAttribute="height" constant="15" id="IEP-cO-Um6"/> - </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="HDO-WC-RvJ"> - <rect key="frame" x="10" y="162" width="51" height="31"/> - <connections> - <action selector="switchPasswordProtectChangedWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="wGL-du-81Q"/> - </connections> - </switch> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Password protect" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HaY-OM-mQh"> - <rect key="frame" x="70" y="170" width="170" height="15"/> - <constraints> - <constraint firstAttribute="height" constant="15" id="MeH-bs-tZK"/> - </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="e1F-PV-32s"> - <rect key="frame" x="70" y="195" width="170" height="30"/> - <constraints> - <constraint firstAttribute="height" constant="30" id="tTv-8w-kxm"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="13"/> - <textInputTraits key="textInputTraits" secureTextEntry="YES" textContentType="password"/> - <connections> - <action selector="fieldPasswordProtectDidEndOnExitWithTextField:" destination="iN0-l3-epB" eventType="editingDidEndOnExit" id="2PO-wf-bHs"/> - </connections> - </textField> - <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="245" width="51" height="31"/> - <connections> - <action selector="switchSetExpirationDateWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="26x-ld-Jsj"/> - </connections> - </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="253" width="170" 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="278" width="170" height="30"/> - <constraints> - <constraint firstAttribute="height" constant="30" id="G4f-LN-v7k"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="13"/> - <textInputTraits key="textInputTraits"/> - <connections> - <action selector="fieldSetExpirationDateWithSender:" destination="iN0-l3-epB" eventType="editingDidBegin" id="5Ou-k5-UM5"/> - </connections> - </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="328" 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="333" width="175" 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="358" width="170" height="30"/> - <constraints> - <constraint firstAttribute="height" constant="30" id="hye-cf-nPD"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="13"/> - <textInputTraits key="textInputTraits"/> - <connections> - <action selector="fieldNoteToRecipientDidEndOnExitWithTextField:" destination="iN0-l3-epB" eventType="editingDidEndOnExit" id="Z9v-qs-dp4"/> - </connections> - </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="408" 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="Delete share link" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ff4-JE-zGU"> - <rect key="frame" x="70" y="413" width="170" 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="408" width="217" height="25"/> - <constraints> - <constraint firstAttribute="height" constant="25" id="fWP-XF-kQx"/> - </constraints> - <connections> - <action selector="buttonDeleteShareLinkWithSender:" destination="iN0-l3-epB" eventType="touchUpInside" id="ANe-oV-NCX"/> - </connections> - </button> - <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="add" translatesAutoresizingMaskIntoConstraints="NO" id="6SU-Ak-Q7m"> - <rect key="frame" x="13" y="453" width="25" height="25"/> - <constraints> - <constraint firstAttribute="width" constant="25" id="NLr-qc-w3G"/> - <constraint firstAttribute="height" constant="25" id="wkp-ks-jJM"/> - </constraints> - </imageView> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Add another link" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cna-iK-PD7"> - <rect key="frame" x="70" y="458" width="170" height="15"/> - <constraints> - <constraint firstAttribute="height" constant="15" id="p9o-oI-gWq"/> - </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="0bK-Kl-hcs"> - <rect key="frame" x="13" y="453" width="217" height="25"/> - <constraints> - <constraint firstAttribute="height" constant="25" id="wQO-6d-vWV"/> - </constraints> - <connections> - <action selector="buttonAddAnotherLinkWithSender:" destination="iN0-l3-epB" eventType="touchUpInside" id="1Ea-g9-pQ8"/> - </connections> - </button> - </subviews> - <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="HaY-OM-mQh" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="4CZ-Mo-lOP"/> - <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 firstItem="0bK-Kl-hcs" firstAttribute="top" secondItem="CLA-UL-mYb" secondAttribute="bottom" constant="20" id="Bka-Hj-Arm"/> - <constraint firstAttribute="trailing" secondItem="ymk-0u-ddH" secondAttribute="trailing" constant="10" id="Chd-iQ-EdR"/> - <constraint firstAttribute="trailing" secondItem="AjK-Ty-MRn" secondAttribute="trailing" constant="10" id="Cjo-Gm-Fqi"/> - <constraint firstItem="KXo-cP-gkc" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="CuB-lc-pHi"/> - <constraint firstItem="UIn-eq-hkP" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="FwN-Rj-koX"/> - <constraint firstItem="HDO-WC-RvJ" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="GTl-Tq-cLY"/> - <constraint firstItem="IHP-P8-rm2" firstAttribute="centerY" secondItem="sjf-wF-y07" secondAttribute="centerY" id="HiA-pE-L6l"/> - <constraint firstItem="6SU-Ak-Q7m" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="13" id="Hqf-wy-u3S"/> - <constraint firstAttribute="trailing" secondItem="e1F-PV-32s" secondAttribute="trailing" constant="10" id="ImT-sr-UAr"/> - <constraint firstAttribute="trailing" secondItem="0bK-Kl-hcs" secondAttribute="trailing" constant="20" id="Jy3-Qb-ucs"/> - <constraint firstAttribute="trailing" secondItem="cna-iK-PD7" secondAttribute="trailing" constant="10" id="LEz-3F-g5Q"/> - <constraint firstAttribute="trailing" secondItem="grT-sd-j7q" secondAttribute="trailing" constant="5" id="Nyn-RD-jTz"/> - <constraint firstItem="6SU-Ak-Q7m" firstAttribute="top" secondItem="CLA-UL-mYb" secondAttribute="bottom" constant="20" id="OU0-vG-YTq"/> - <constraint firstAttribute="trailing" secondItem="FyH-3p-EdC" secondAttribute="trailing" constant="10" id="RhU-wl-afT"/> - <constraint firstItem="KXo-cP-gkc" firstAttribute="centerY" secondItem="UIn-eq-hkP" secondAttribute="centerY" id="Snt-zf-mcs"/> - <constraint firstItem="sjf-wF-y07" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="TFC-63-muN"/> - <constraint firstItem="dB8-1M-WZr" firstAttribute="top" secondItem="e1F-PV-32s" secondAttribute="bottom" constant="20" id="TIV-5L-Cza"/> - <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="HaY-OM-mQh" firstAttribute="centerY" secondItem="HDO-WC-RvJ" secondAttribute="centerY" id="UcN-gf-Prv"/> - <constraint firstItem="e1F-PV-32s" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="YCZ-Z6-1Ty"/> - <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="cna-iK-PD7" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="aZc-3Q-liP"/> - <constraint firstItem="F4T-wQ-tBU" firstAttribute="top" secondItem="ymk-0u-ddH" secondAttribute="bottom" constant="20" id="aj8-2w-ySe"/> - <constraint firstItem="0bK-Kl-hcs" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="13" id="bSd-GG-kS3"/> - <constraint firstItem="HDO-WC-RvJ" firstAttribute="top" secondItem="UIn-eq-hkP" secondAttribute="bottom" constant="20" id="dex-mb-oRg"/> - <constraint firstItem="AjK-Ty-MRn" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="eT2-WG-2Db"/> - <constraint firstItem="hr8-Qe-xD0" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="13" id="elF-be-kqS"/> - <constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="0bK-Kl-hcs" secondAttribute="bottom" constant="10" id="eyC-io-Nk6"/> - <constraint firstItem="cna-iK-PD7" firstAttribute="centerY" secondItem="0bK-Kl-hcs" secondAttribute="centerY" id="fDj-O7-Xdr"/> - <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 firstItem="e1F-PV-32s" firstAttribute="top" secondItem="HaY-OM-mQh" secondAttribute="bottom" constant="10" id="m5R-ms-HZh"/> - <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 firstItem="sjf-wF-y07" firstAttribute="top" secondItem="AjK-Ty-MRn" secondAttribute="bottom" constant="20" id="suK-qu-fvy"/> - <constraint firstAttribute="trailing" secondItem="KXo-cP-gkc" secondAttribute="trailing" constant="10" id="uDa-6r-K84"/> - <constraint firstItem="AjK-Ty-MRn" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="vWx-aM-wFJ"/> - <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 firstAttribute="trailing" secondItem="HaY-OM-mQh" secondAttribute="trailing" constant="10" id="yvI-xV-T7d"/> - <constraint firstItem="Ff4-JE-zGU" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="zc7-db-OeN"/> - <constraint firstItem="UIn-eq-hkP" firstAttribute="top" secondItem="sjf-wF-y07" secondAttribute="bottom" constant="20" id="zex-fG-9ns"/> - </constraints> - <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> - <connections> - <outlet property="buttonAddAnotherLink" destination="0bK-Kl-hcs" id="XMo-Cp-y6f"/> - <outlet property="buttonDeleteShareLink" destination="CLA-UL-mYb" id="LVP-Vh-RHb"/> - <outlet property="fieldLabel" destination="AjK-Ty-MRn" id="qar-eZ-ctz"/> - <outlet property="fieldNoteToRecipient" destination="FyH-3p-EdC" id="EBz-iA-1tq"/> - <outlet property="fieldPasswordProtect" destination="e1F-PV-32s" id="c1Y-0f-UYD"/> - <outlet property="fieldSetExpirationDate" destination="ymk-0u-ddH" id="W6o-xf-Zj2"/> - <outlet property="imageAddAnotherLink" destination="6SU-Ak-Q7m" id="Is7-q2-ZJu"/> - <outlet property="imageDeleteShareLink" destination="hr8-Qe-xD0" id="hGE-fg-rnv"/> - <outlet property="imageNoteToRecipient" destination="F4T-wQ-tBU" id="IHc-Q2-VxM"/> - <outlet property="labelAddAnotherLink" destination="cna-iK-PD7" id="xax-ip-GpR"/> - <outlet property="labelAllowEditing" destination="IHP-P8-rm2" id="bfP-WI-ryB"/> - <outlet property="labelDeleteShareLink" destination="Ff4-JE-zGU" id="7jH-iS-zf8"/> - <outlet property="labelHideDownload" destination="KXo-cP-gkc" id="vis-Zu-pga"/> - <outlet property="labelNoteToRecipient" destination="grT-sd-j7q" id="yOv-Ke-EnF"/> - <outlet property="labelPasswordProtect" destination="HaY-OM-mQh" id="nlG-u7-v1H"/> - <outlet property="labelSetExpirationDate" destination="qll-9F-4DA" id="K8B-Ys-V8e"/> - <outlet property="switchAllowEditing" destination="sjf-wF-y07" id="8J2-kj-Ugp"/> - <outlet property="switchHideDownload" destination="UIn-eq-hkP" id="25D-zI-MEj"/> - <outlet property="switchPasswordProtect" destination="HDO-WC-RvJ" id="K7a-3i-8kx"/> - <outlet property="switchSetExpirationDate" destination="dB8-1M-WZr" id="R5d-Hf-ga6"/> - </connections> - <point key="canvasLocation" x="-60" y="350.625"/> - </view> - </objects> - <resources> - <image name="add" width="25" height="25"/> - <image name="file_txt" width="300" height="300"/> - <image name="trash" width="512" height="512"/> - </resources> -</document> diff --git a/iOSClient/Share/NCShareNetworking.swift b/iOSClient/Share/NCShareNetworking.swift index 04052ec9b..cb65673c2 100644 --- a/iOSClient/Share/NCShareNetworking.swift +++ b/iOSClient/Share/NCShareNetworking.swift @@ -53,8 +53,8 @@ class NCShareNetworking: NSObject { NCUtility.shared.stopActivityIndicator() } - if errorCode == 0 && shares != nil { - NCManageDatabase.shared.addShare(urlBase: self.urlBase, account: self.metadata.account, shares: shares!) + if errorCode == 0, let shares = shares { + NCManageDatabase.shared.addShare(urlBase: self.urlBase, account: self.metadata.account, shares: shares) self.appDelegate.shares = NCManageDatabase.shared.getTableShares(account: self.metadata.account) } else { NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCGlobal.shared.errorInternalError) @@ -62,35 +62,27 @@ class NCShareNetworking: NSObject { self.delegate?.readShareCompleted() } } - - func createShareLink(password: String?) { - NCUtility.shared.startActivityIndicator(backgroundView: view, blurEffect: false) - let filenamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: urlBase, account: metadata.account)! - NCCommunication.shared.createShareLink(path: filenamePath, password: password) { account, share, errorCode, errorDescription in - NCUtility.shared.stopActivityIndicator() - if errorCode == 0 && share != nil { - NCManageDatabase.shared.addShare(urlBase: self.urlBase, account: self.metadata.account, shares: [share!]) - self.appDelegate.shares = NCManageDatabase.shared.getTableShares(account: self.metadata.account) - } else if errorCode != 0 { - NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCGlobal.shared.errorInternalError) - } - self.delegate?.shareCompleted() - } - } - func createShare(shareWith: String, shareType: Int, password: String?, metadata: tableMetadata) { + func createShare(option: NCTableShareable) { + // NOTE: Permissions don't work for creating with file drop! + // https://github.com/nextcloud/server/issues/17504 + + // NOTE: Can't save label, expirationDate, and note in same request. + // Library update needed: + // https://github.com/nextcloud/ios-communication-library/pull/104 + NCUtility.shared.startActivityIndicator(backgroundView: view, blurEffect: false) let filenamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, urlBase: urlBase, account: metadata.account)! - var permission: Int = NCManageDatabase.shared.getCapabilitiesServerInt(account: metadata.account, elements: ["ocs", "data", "capabilities", "files_sharing", "default_permissions"]) - if permission <= 0 { - permission = metadata.directory ? NCGlobal.shared.permissionMaxFolderShare : NCGlobal.shared.permissionMaxFileShare - } - NCCommunication.shared.createShare(path: filenamePath, shareType: shareType, shareWith: shareWith, password: password, permissions: permission) { (account, share, errorCode, errorDescription) in + NCCommunication.shared.createShare(path: filenamePath, shareType: option.shareType, shareWith: option.shareWith, password: option.password, permissions: option.permissions) { (account, share, errorCode, errorDescription) in NCUtility.shared.stopActivityIndicator() - if errorCode == 0 && share != nil { - NCManageDatabase.shared.addShare(urlBase: self.urlBase, account: self.metadata.account, shares: [share!]) + if errorCode == 0, let share = share { + option.idShare = share.idShare + NCManageDatabase.shared.addShare(urlBase: self.urlBase, account: self.metadata.account, shares: [share]) self.appDelegate.shares = NCManageDatabase.shared.getTableShares(account: self.metadata.account) + if option.hasChanges(comparedTo: share) { + self.updateShare(option: option) + } } else { NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCGlobal.shared.errorInternalError) } @@ -111,17 +103,17 @@ class NCShareNetworking: NSObject { } } - func updateShare(idShare: Int, password: String?, permissions: Int, note: String?, label: String?, expirationDate: String?, hideDownload: Bool) { + func updateShare(option: NCTableShareable) { NCUtility.shared.startActivityIndicator(backgroundView: view, blurEffect: false) - NCCommunication.shared.updateShare(idShare: idShare, password: password, expireDate: expirationDate, permissions: permissions, note: note, label: label, hideDownload: hideDownload) { account, share, errorCode, errorDescription in + NCCommunication.shared.updateShare(idShare: option.idShare, password: option.password, expireDate: option.expDateString, permissions: option.permissions, note: option.note, label: option.label, hideDownload: option.hideDownload) { account, share, errorCode, errorDescription in NCUtility.shared.stopActivityIndicator() - if errorCode == 0 && share != nil { - NCManageDatabase.shared.addShare(urlBase: self.urlBase, account: self.metadata.account, shares: [share!]) + if errorCode == 0, let share = share { + NCManageDatabase.shared.addShare(urlBase: self.urlBase, account: self.metadata.account, shares: [share]) self.appDelegate.shares = NCManageDatabase.shared.getTableShares(account: self.metadata.account) self.delegate?.readShareCompleted() } else { NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: NCGlobal.shared.errorInternalError) - self.delegate?.updateShareWithError(idShare: idShare) + self.delegate?.updateShareWithError(idShare: option.idShare) } } } diff --git a/iOSClient/Share/NCSharePaging.swift b/iOSClient/Share/NCSharePaging.swift index fdf8d59d0..c86f79b4b 100644 --- a/iOSClient/Share/NCSharePaging.swift +++ b/iOSClient/Share/NCSharePaging.swift @@ -27,14 +27,19 @@ import Parchment import NCCommunication import MarqueeLabel +protocol NCSharePagingContent { + var textField: UITextField? { get } +} + class NCSharePaging: UIViewController { private let pagingViewController = NCShareHeaderViewController() - private let appDelegate = UIApplication.shared.delegate as! AppDelegate + private weak var appDelegate = UIApplication.shared.delegate as? AppDelegate private var activityEnabled = true private var commentsEnabled = true private var sharingEnabled = true + private var currentVC: NCSharePagingContent? @objc var metadata = tableMetadata() var indexPage = NCGlobal.NCSharePagingIndex.activity @@ -47,28 +52,9 @@ class NCSharePaging: UIViewController { view.backgroundColor = NCBrandColor.shared.systemBackground navigationItem.leftBarButtonItem = UIBarButtonItem(title: NSLocalizedString("_close_", comment: ""), style: .done, target: self, action: #selector(exitTapped)) - - // Verify Comments & Sharing enabled - let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: appDelegate.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor) - let comments = NCManageDatabase.shared.getCapabilitiesServerBool(account: appDelegate.account, elements: NCElementsJSON.shared.capabilitiesFilesComments, exists: false) - if serverVersionMajor >= NCGlobal.shared.nextcloudVersion20 && comments == false { - commentsEnabled = false - } - let sharing = NCManageDatabase.shared.getCapabilitiesServerBool(account: appDelegate.account, elements: NCElementsJSON.shared.capabilitiesFileSharingApiEnabled, exists: false) - if sharing == false { - sharingEnabled = false - } - let activity = NCManageDatabase.shared.getCapabilitiesServerArray(account: appDelegate.account, elements: NCElementsJSON.shared.capabilitiesActivity) - if activity == nil { - activityEnabled = false - } - if indexPage == .sharing && !sharingEnabled { - indexPage = .activity - } - if indexPage == .activity && !activityEnabled && sharingEnabled { - indexPage = .sharing - } - + NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil) + setupCapabilities() // *** MUST BE THE FIRST ONE *** pagingViewController.metadata = metadata @@ -97,26 +83,53 @@ class NCSharePaging: UIViewController { // 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) + pagingViewController.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + pagingViewController.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), + pagingViewController.view.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), + pagingViewController.view.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor) ]) pagingViewController.dataSource = self pagingViewController.delegate = self pagingViewController.select(index: indexPage.rawValue) - let pagingIndexItem = self.pagingViewController(pagingViewController, pagingItemAt: indexPage.rawValue) as! PagingIndexItem - self.title = pagingIndexItem.title + let pagingIndexItem = self.pagingViewController(pagingViewController, pagingItemAt: indexPage.rawValue) as? PagingIndexItem + self.title = pagingIndexItem?.title NotificationCenter.default.addObserver(self, selector: #selector(self.changeTheming), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterChangeTheming), object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.orientationDidChange), name: UIDevice.orientationDidChangeNotification, object: nil) changeTheming() } + func setupCapabilities() { + guard let appDelegate = appDelegate else { return } + + // Verify Comments & Sharing enabled + let serverVersionMajor = NCManageDatabase.shared.getCapabilitiesServerInt(account: appDelegate.account, elements: NCElementsJSON.shared.capabilitiesVersionMajor) + let comments = NCManageDatabase.shared.getCapabilitiesServerBool(account: appDelegate.account, elements: NCElementsJSON.shared.capabilitiesFilesComments, exists: false) + if serverVersionMajor >= NCGlobal.shared.nextcloudVersion20 && comments == false { + commentsEnabled = false + } + let sharing = NCManageDatabase.shared.getCapabilitiesServerBool(account: appDelegate.account, elements: NCElementsJSON.shared.capabilitiesFileSharingApiEnabled, exists: false) + sharingEnabled = sharing + let activity = NCManageDatabase.shared.getCapabilitiesServerArray(account: appDelegate.account, elements: NCElementsJSON.shared.capabilitiesActivity) + activityEnabled = activity != nil + + if indexPage == .sharing && !sharingEnabled { + indexPage = .activity + } + if indexPage == .activity && !activityEnabled && sharingEnabled { + indexPage = .sharing + } + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + currentVC = pagingViewController.pageViewController.selectedViewController as? NCSharePagingContent + } + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - - if appDelegate.disableSharesView { + if appDelegate?.disableSharesView == true { self.dismiss(animated: false, completion: nil) } @@ -127,21 +140,53 @@ class NCSharePaging: UIViewController { override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) - NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataSource, userInfo: ["ocId": metadata.ocId, "serverUrl": metadata.serverUrl]) } - @objc func exitTapped() { - self.dismiss(animated: true, completion: nil) + deinit { + NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil) + NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardDidShowNotification, object: nil) + NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil) } // MARK: - NotificationCenter + @objc func orientationDidChange() { + pagingViewController.menuItemSize = .fixed( + width: self.view.bounds.width / CGFloat(NCGlobal.NCSharePagingIndex.allCases.count), + height: 40) + currentVC?.textField?.resignFirstResponder() + } + @objc func changeTheming() { pagingViewController.indicatorColor = NCBrandColor.shared.brandElement - (pagingViewController.view as! NCSharePagingView).setupConstraints() + (pagingViewController.view as? NCSharePagingView)?.setupConstraints() pagingViewController.reloadMenu() } + + // MARK: - Keyboard & TextField + @objc func keyboardWillShow(notification: Notification) { + let frameEndUserInfoKey = UIResponder.keyboardFrameEndUserInfoKey + + guard let info = notification.userInfo, + let textField = currentVC?.textField, + let centerObject = textField.superview?.convert(textField.center, to: nil), + let keyboardFrame = info[frameEndUserInfoKey] as? CGRect + else { return } + + let diff = keyboardFrame.origin.y - centerObject.y - textField.frame.height + if diff < 0 { + view.frame.origin.y = diff + } + } + + @objc func keyboardWillHide(notification: NSNotification) { + view.frame.origin.y = 0 + } + + @objc func exitTapped() { + self.dismiss(animated: true, completion: nil) + } } // MARK: - PagingViewController Delegate @@ -155,13 +200,14 @@ extension NCSharePaging: PagingViewControllerDelegate { let itemIndex = NCGlobal.NCSharePagingIndex(rawValue: item.index) else { return } - if itemIndex == .activity && !activityEnabled { - pagingViewController.contentInteraction = .none - } else if itemIndex == .sharing && !sharingEnabled { + if itemIndex == .activity && !activityEnabled || itemIndex == .sharing && !sharingEnabled { pagingViewController.contentInteraction = .none } else { self.title = item.title } + + currentVC?.textField?.resignFirstResponder() + self.currentVC = destinationViewController as? NCSharePagingContent } } @@ -171,11 +217,13 @@ extension NCSharePaging: PagingViewControllerDataSource { func pagingViewController(_: PagingViewController, viewControllerAt index: Int) -> UIViewController { - let height = pagingViewController.options.menuHeight + NCSharePagingView.HeaderHeight + let height = pagingViewController.options.menuHeight + NCSharePagingView.headerHeight switch NCGlobal.NCSharePagingIndex(rawValue: index) { case .activity: - let viewController = UIStoryboard(name: "NCActivity", bundle: nil).instantiateInitialViewController() as! NCActivity + guard let viewController = UIStoryboard(name: "NCActivity", bundle: nil).instantiateInitialViewController() as? NCActivity else { + return UIViewController() + } viewController.height = height viewController.showComments = true viewController.didSelectItemEnable = false @@ -183,7 +231,9 @@ extension NCSharePaging: PagingViewControllerDataSource { viewController.objectType = "files" return viewController case .sharing: - let viewController = UIStoryboard(name: "NCShare", bundle: nil).instantiateViewController(withIdentifier: "sharing") as! NCShare + guard let viewController = UIStoryboard(name: "NCShare", bundle: nil).instantiateViewController(withIdentifier: "sharing") as? NCShare else { + return UIViewController() + } viewController.sharingEnabled = sharingEnabled viewController.metadata = metadata viewController.height = height @@ -231,18 +281,16 @@ class NCShareHeaderViewController: PagingViewController { } override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - if NCGlobal.NCSharePagingIndex(rawValue: indexPath.item) == .activity && !activityEnabled { - return - } else if NCGlobal.NCSharePagingIndex(rawValue: indexPath.item) == .sharing && !sharingEnabled { - return - } + guard NCGlobal.NCSharePagingIndex(rawValue: indexPath.item) != .activity || activityEnabled, + NCGlobal.NCSharePagingIndex(rawValue: indexPath.item) != .sharing || sharingEnabled + else { return } super.collectionView(collectionView, didSelectItemAt: indexPath) } } class NCSharePagingView: PagingView { - static let HeaderHeight: CGFloat = 250 + static let headerHeight: CGFloat = 100 var metadata = tableMetadata() var headerHeightConstraint: NSLayoutConstraint? @@ -261,7 +309,7 @@ class NCSharePagingView: PagingView { override func setupConstraints() { - let headerView = Bundle.main.loadNibNamed("NCShareHeaderView", owner: self, options: nil)?.first as! NCShareHeaderView + guard let headerView = Bundle.main.loadNibNamed("NCShareHeaderView", owner: self, options: nil)?.first as? NCShareHeaderView else { return } headerView.backgroundColor = NCBrandColor.shared.systemBackground headerView.ocId = metadata.ocId @@ -269,9 +317,9 @@ class NCSharePagingView: PagingView { headerView.imageView.image = UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) } else { if metadata.directory { - let image = UIImage(named: "folder")! - headerView.imageView.image = image.image(color: NCBrandColor.shared.brandElement, size: image.size.width) - } else if metadata.iconName.count > 0 { + let image = UIImage(named: "folder") + headerView.imageView.image = image?.image(color: NCBrandColor.shared.brandElement, size: image?.size.width ?? 0) + } else if !metadata.iconName.isEmpty { headerView.imageView.image = UIImage(named: metadata.iconName) } else { headerView.imageView.image = UIImage(named: "file") @@ -292,9 +340,7 @@ class NCSharePagingView: PagingView { collectionView.translatesAutoresizingMaskIntoConstraints = false headerView.translatesAutoresizingMaskIntoConstraints = false - headerHeightConstraint = headerView.heightAnchor.constraint( - equalToConstant: NCSharePagingView.HeaderHeight - ) + headerHeightConstraint = headerView.heightAnchor.constraint(equalToConstant: NCSharePagingView.headerHeight) headerHeightConstraint?.isActive = true NSLayoutConstraint.activate([ @@ -325,32 +371,26 @@ class NCShareHeaderView: UIView { override func awakeFromNib() { super.awakeFromNib() - let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.longTap)) path.addGestureRecognizer(longGesture) } @IBAction func touchUpInsideFavorite(_ sender: UIButton) { - if let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) { - NCNetworking.shared.favoriteMetadata(metadata) { errorCode, errorDescription in - if errorCode == 0 { - if !metadata.favorite { - self.favorite.setImage(NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.yellowFavorite, size: 20), for: .normal) - } else { - self.favorite.setImage(NCUtility.shared.loadImage(named: "star.fill", color: NCBrandColor.shared.systemGray, size: 20), for: .normal) - } - } else { - NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode) - } + guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) else { return } + NCNetworking.shared.favoriteMetadata(metadata) { errorCode, errorDescription in + if errorCode == 0 { + self.favorite.setImage(NCUtility.shared.loadImage( + named: "star.fill", + color: metadata.favorite ? NCBrandColor.shared.yellowFavorite : NCBrandColor.shared.systemGray, + size: 20), for: .normal) + } else { + NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.error, errorCode: errorCode) } } } @objc func longTap(sender: UIGestureRecognizer) { - - let board = UIPasteboard.general - board.string = path.text - + UIPasteboard.general.string = path.text NCContentPresenter.shared.messageNotification("", description: "_copied_path_", delay: NCGlobal.shared.dismissAfterSecond, type: NCContentPresenter.messageType.info, errorCode: NCGlobal.shared.errorNoError) } } diff --git a/iOSClient/Share/NCShareQuickStatusMenu.swift b/iOSClient/Share/NCShareQuickStatusMenu.swift deleted file mode 100644 index 71d4a4be6..000000000 --- a/iOSClient/Share/NCShareQuickStatusMenu.swift +++ /dev/null @@ -1,66 +0,0 @@ -// -// NCShareQuickStatusMenu.swift -// Nextcloud -// -// Created by TSI-mc on 30/06/21. -// Copyright © 2021 Marino Faggiana. All rights reserved. -// - -import UIKit - -class NCShareQuickStatusMenu: NSObject { - - func toggleMenu(viewController: UIViewController, directory: Bool, tableShare: tableShare) { - - print(tableShare.permissions) - let menuViewController = UIStoryboard(name: "NCMenu", bundle: nil).instantiateInitialViewController() as! NCMenu - var actions = [NCMenuAction]() - - actions.append( - NCMenuAction( - title: NSLocalizedString("_share_read_only_", comment: ""), - icon: UIImage(), - selected: tableShare.permissions == (NCGlobal.shared.permissionReadShare + NCGlobal.shared.permissionShareShare) || tableShare.permissions == NCGlobal.shared.permissionReadShare, - on: false, - action: { _ in - let canShare = CCUtility.isPermission(toCanShare: tableShare.permissions) - let permissions = CCUtility.getPermissionsValue(byCanEdit: false, andCanCreate: false, andCanChange: false, andCanDelete: false, andCanShare: canShare, andIsFolder: directory) - NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterShareChangePermissions, userInfo: ["idShare": tableShare.idShare, "permissions": permissions, "hideDownload": tableShare.hideDownload]) - } - ) - ) - - actions.append( - NCMenuAction( - title: directory ? NSLocalizedString("_share_allow_upload_", comment: "") : NSLocalizedString("_share_editing_", comment: ""), - icon: UIImage(), - selected: hasUploadPermission(tableShare: tableShare), - on: false, - action: { _ in - let canShare = CCUtility.isPermission(toCanShare: tableShare.permissions) - let permissions = CCUtility.getPermissionsValue(byCanEdit: true, andCanCreate: true, andCanChange: true, andCanDelete: true, andCanShare: canShare, andIsFolder: directory) - NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterShareChangePermissions, userInfo: ["idShare": tableShare.idShare, "permissions": permissions, "hideDownload": tableShare.hideDownload]) - } - ) - ) - - menuViewController.actions = actions - - let menuPanelController = NCMenuPanelController() - menuPanelController.parentPresenter = viewController - menuPanelController.delegate = menuViewController - menuPanelController.set(contentViewController: menuViewController) - menuPanelController.track(scrollView: menuViewController.tableView) - - viewController.present(menuPanelController, animated: true, completion: nil) - } - - fileprivate func hasUploadPermission(tableShare: tableShare) -> Bool { - let uploadPermissions = [ - NCGlobal.shared.permissionMaxFileShare, - NCGlobal.shared.permissionMaxFolderShare, - NCGlobal.shared.permissionDefaultFileRemoteShareNoSupportShareOption, - NCGlobal.shared.permissionDefaultFolderRemoteShareNoSupportShareOption] - return uploadPermissions.contains(tableShare.permissions) - } -} diff --git a/iOSClient/Share/NCShareUserCell.swift b/iOSClient/Share/NCShareUserCell.swift index c20fe3dc0..08e463697 100644 --- a/iOSClient/Share/NCShareUserCell.swift +++ b/iOSClient/Share/NCShareUserCell.swift @@ -22,6 +22,7 @@ import UIKit import DropDown +import NCCommunication class NCShareUserCell: UITableViewCell, NCCellProtocol { @@ -37,24 +38,48 @@ class NCShareUserCell: UITableViewCell, NCCellProtocol { var tableShare: tableShare? weak var delegate: NCShareUserCellDelegate? - var fileAvatarImageView: UIImageView? { - get { - return imageItem - } - } - var fileObjectId: String? { - get { - return nil + var fileAvatarImageView: UIImageView? { return imageItem } + var fileObjectId: String? { return nil } + var filePreviewImageView: UIImageView? { return nil } + var fileUser: String? { return tableShare?.shareWith } + + func setupCellUI(userId: String) { + guard let tableShare = tableShare else { + return } - } - var filePreviewImageView: UIImageView? { - get { - return nil + + labelTitle.text = tableShare.shareWithDisplayname + labelTitle.textColor = NCBrandColor.shared.label + isUserInteractionEnabled = true + labelQuickStatus.isHidden = false + imageDownArrow.isHidden = false + buttonMenu.isHidden = false + imageItem.image = NCShareCommon.shared.getImageShareType(shareType: tableShare.shareType) + + let status = NCUtility.shared.getUserStatus(userIcon: tableShare.userIcon, userStatus: tableShare.userStatus, userMessage: tableShare.userMessage) + imageStatus.image = status.onlineStatus + self.status.text = status.statusMessage + + // If the initiator or the recipient is not the current user, show the list of sharees without any options to edit it. + if tableShare.uidOwner != userId && tableShare.uidFileOwner != userId { + isUserInteractionEnabled = false + labelQuickStatus.isHidden = true + imageDownArrow.isHidden = true + buttonMenu.isHidden = true } - } - var fileUser: String? { - get { - return tableShare?.shareWith + + btnQuickStatus.setTitle("", for: .normal) + btnQuickStatus.contentHorizontalAlignment = .left + + if tableShare.permissions == NCGlobal.shared.permissionCreateShare { + labelQuickStatus.text = NSLocalizedString("_share_file_drop_", comment: "") + } else { + // Read Only + if CCUtility.isAnyPermission(toEdit: tableShare.permissions) { + labelQuickStatus.text = NSLocalizedString("_share_editing_", comment: "") + } else { + labelQuickStatus.text = NSLocalizedString("_share_read_only_", comment: "") + } } } @@ -63,7 +88,7 @@ class NCShareUserCell: UITableViewCell, NCCellProtocol { let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapAvatarImage)) imageItem?.addGestureRecognizer(tapGesture) - buttonMenu.setImage(UIImage(named: "shareMenu")!.image(color: .gray, size: 50), for: .normal) + buttonMenu.setImage(UIImage(named: "shareMenu")?.image(color: .gray, size: 50), for: .normal) labelQuickStatus.textColor = NCBrandColor.shared.customer imageDownArrow.image = NCUtility.shared.loadImage(named: "arrowtriangle.down.fill", color: NCBrandColor.shared.customer) } @@ -87,9 +112,9 @@ protocol NCShareUserCellDelegate: AnyObject { func quickStatus(with tableShare: tableShare?, sender: Any) } -// MARK: - NCShareUserDropDownCell +// MARK: - NCSearchUserDropDownCell -class NCShareUserDropDownCell: DropDownCell, NCCellProtocol { +class NCSearchUserDropDownCell: DropDownCell, NCCellProtocol { @IBOutlet weak var imageItem: UIImageView! @IBOutlet weak var imageStatus: UIImageView! @@ -99,21 +124,9 @@ class NCShareUserDropDownCell: DropDownCell, NCCellProtocol { private var user: String = "" - var fileAvatarImageView: UIImageView? { - get { - return imageItem - } - } - var fileObjectId: String? { - get { - return nil - } - } - var filePreviewImageView: UIImageView? { - get { - return nil - } - } + var fileAvatarImageView: UIImageView? { return imageItem } + var fileObjectId: String? { return nil } + var filePreviewImageView: UIImageView? { return nil } var fileUser: String? { get { return user @@ -122,4 +135,44 @@ class NCShareUserDropDownCell: DropDownCell, NCCellProtocol { user = newValue ?? "" } } + + func setupCell(sharee: NCCommunicationSharee, baseUrl: NCUserBaseUrl) { + imageItem.image = NCShareCommon.shared.getImageShareType(shareType: sharee.shareType) + imageShareeType.image = NCShareCommon.shared.getImageShareType(shareType: sharee.shareType) + let status = NCUtility.shared.getUserStatus(userIcon: sharee.userIcon, userStatus: sharee.userStatus, userMessage: sharee.userMessage) + imageStatus.image = status.onlineStatus + self.status.text = status.statusMessage + if self.status.text?.count ?? 0 > 0 { + centerTitle.constant = -5 + } else { + centerTitle.constant = 0 + } + + imageItem.image = NCUtility.shared.loadUserImage( + for: sharee.shareWith, + displayName: nil, + userBaseUrl: baseUrl) + + let fileName = baseUrl.userBaseUrl + "-" + sharee.shareWith + ".png" + if NCManageDatabase.shared.getImageAvatarLoaded(fileName: fileName) == nil { + let fileNameLocalPath = String(CCUtility.getDirectoryUserData()) + "/" + fileName + let etag = NCManageDatabase.shared.getTableAvatar(fileName: fileName)?.etag + + NCCommunication.shared.downloadAvatar( + user: sharee.shareWith, + fileNameLocalPath: fileNameLocalPath, + sizeImage: NCGlobal.shared.avatarSize, + avatarSizeRounded: NCGlobal.shared.avatarSizeRounded, + etag: etag) { _, imageAvatar, _, etag, errorCode, _ in + + if errorCode == 0, let etag = etag, let imageAvatar = imageAvatar { + NCManageDatabase.shared.addAvatar(fileName: fileName, etag: etag) + self.imageItem.image = imageAvatar + } else if errorCode == NCGlobal.shared.errorNotModified, let imageAvatar = NCManageDatabase.shared.setAvatarLoaded(fileName: fileName) { + self.imageItem.image = imageAvatar + } + } + } + + } } diff --git a/iOSClient/Share/NCShareUserFolderMenuView.xib b/iOSClient/Share/NCShareUserFolderMenuView.xib deleted file mode 100644 index 2908ef2a1..000000000 --- a/iOSClient/Share/NCShareUserFolderMenuView.xib +++ /dev/null @@ -1,226 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES"> - <device id="retina3_5" orientation="portrait" appearance="light"/> - <dependencies> - <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/> - <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="250" height="420"/> - <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"/> - <connections> - <action selector="switchCanReshareChangedWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="Ezn-AP-uEh"/> - </connections> - </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="170" 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="214" width="51" height="31"/> - <connections> - <action selector="switchSetExpirationDateWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="A9c-YF-bXd"/> - </connections> - </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="222" width="170" 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="247" width="170" height="30"/> - <constraints> - <constraint firstAttribute="height" constant="30" id="G4f-LN-v7k"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="13"/> - <textInputTraits key="textInputTraits"/> - <connections> - <action selector="fieldSetExpirationDateWithSender:" destination="iN0-l3-epB" eventType="editingDidEndOnExit" id="WdF-Ie-Di0"/> - </connections> - </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="297" 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="302" width="175" 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="327" width="170" height="34"/> - <fontDescription key="fontDescription" type="system" pointSize="14"/> - <textInputTraits key="textInputTraits"/> - <connections> - <action selector="fieldNoteToRecipientDidEndOnExitWithTextField:" destination="iN0-l3-epB" eventType="editingDidEndOnExit" id="q1P-u7-EBw"/> - </connections> - </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="381" 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="386" width="170" 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="381" width="217" height="25"/> - <constraints> - <constraint firstAttribute="height" constant="25" id="fWP-XF-kQx"/> - </constraints> - <connections> - <action selector="buttonUnshareWithSender:" destination="iN0-l3-epB" eventType="touchUpInside" id="Nky-nT-rCz"/> - </connections> - </button> - <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="1br-PL-gFf"> - <rect key="frame" x="10" y="61" width="51" height="31"/> - <connections> - <action selector="switchCanCreateWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="M2Z-bc-ZKU"/> - </connections> - </switch> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Can create" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="G13-DS-7uC"> - <rect key="frame" x="70" y="69" width="170" height="15"/> - <constraints> - <constraint firstAttribute="height" constant="15" id="nK7-xW-fbq"/> - </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="0yc-df-C1f"> - <rect key="frame" x="10" y="112" width="51" height="31"/> - <connections> - <action selector="switchCanChangeWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="XIQ-GD-IU7"/> - </connections> - </switch> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Can change" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YWL-Ks-51c"> - <rect key="frame" x="70" y="120" width="170" height="15"/> - <constraints> - <constraint firstAttribute="height" constant="15" id="NYy-3u-P1R"/> - </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="vja-ge-I6S"> - <rect key="frame" x="10" y="163" width="51" height="31"/> - <connections> - <action selector="switchCanDeleteWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="BRV-e3-C17"/> - </connections> - </switch> - <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Can delete" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dZP-fH-9sg"> - <rect key="frame" x="70" y="171" width="170" height="15"/> - <constraints> - <constraint firstAttribute="height" constant="15" id="p6u-3B-cFa"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="13"/> - <nil key="textColor"/> - <nil key="highlightedColor"/> - </label> - </subviews> - <constraints> - <constraint firstItem="Ff4-JE-zGU" firstAttribute="centerY" secondItem="hr8-Qe-xD0" secondAttribute="centerY" id="0WP-PE-HTp"/> - <constraint firstItem="YWL-Ks-51c" firstAttribute="leading" secondItem="0yc-df-C1f" secondAttribute="trailing" constant="11" id="18d-Lv-xE7"/> - <constraint firstItem="dZP-fH-9sg" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="2N4-ol-qeH"/> - <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="vja-ge-I6S" firstAttribute="top" secondItem="0yc-df-C1f" secondAttribute="bottom" constant="20" id="6jy-3A-HWD"/> - <constraint firstItem="FyH-3p-EdC" firstAttribute="top" secondItem="grT-sd-j7q" secondAttribute="bottom" constant="10" id="7al-MO-ezA"/> - <constraint firstItem="dZP-fH-9sg" firstAttribute="centerY" secondItem="vja-ge-I6S" secondAttribute="centerY" id="7ne-dy-Lt1"/> - <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="0yc-df-C1f" firstAttribute="top" secondItem="1br-PL-gFf" secondAttribute="bottom" constant="20" id="FGV-mm-Ko5"/> - <constraint firstItem="G13-DS-7uC" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="70" id="GqL-Dy-FyM"/> - <constraint firstItem="1br-PL-gFf" firstAttribute="top" secondItem="sjf-wF-y07" secondAttribute="bottom" constant="20" id="HCV-Fc-QqK"/> - <constraint firstAttribute="trailing" secondItem="YWL-Ks-51c" secondAttribute="trailing" constant="10" id="HHo-s3-88y"/> - <constraint firstItem="IHP-P8-rm2" firstAttribute="centerY" secondItem="sjf-wF-y07" secondAttribute="centerY" id="HiA-pE-L6l"/> - <constraint firstItem="1br-PL-gFf" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="JKb-Jd-pOz"/> - <constraint firstItem="0yc-df-C1f" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="JYX-ih-uiD"/> - <constraint firstItem="dB8-1M-WZr" firstAttribute="top" secondItem="vja-ge-I6S" secondAttribute="bottom" constant="20" id="NSb-s1-gmD"/> - <constraint firstAttribute="trailing" secondItem="grT-sd-j7q" secondAttribute="trailing" constant="5" id="Nyn-RD-jTz"/> - <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 firstAttribute="trailing" secondItem="dZP-fH-9sg" secondAttribute="trailing" constant="10" id="Y3X-Bg-zXC"/> - <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="G13-DS-7uC" firstAttribute="centerY" secondItem="1br-PL-gFf" secondAttribute="centerY" id="cbx-hu-mhg"/> - <constraint firstItem="hr8-Qe-xD0" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="13" id="elF-be-kqS"/> - <constraint firstAttribute="trailing" secondItem="G13-DS-7uC" secondAttribute="trailing" constant="10" id="gKS-GP-xkX"/> - <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="YWL-Ks-51c" firstAttribute="centerY" secondItem="0yc-df-C1f" secondAttribute="centerY" id="p2G-NK-Qcr"/> - <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 firstItem="vja-ge-I6S" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="10" id="ukl-JN-XFD"/> - <constraint firstAttribute="trailing" secondItem="qll-9F-4DA" secondAttribute="trailing" constant="10" id="vaT-9Q-m84"/> - <constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="CLA-UL-mYb" secondAttribute="bottom" constant="10" id="w6T-Q9-OKA"/> - <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> - <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> - <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="labelCanChange" destination="YWL-Ks-51c" id="3lh-TV-rKt"/> - <outlet property="labelCanCreate" destination="G13-DS-7uC" id="BOR-I2-EVX"/> - <outlet property="labelCanDelete" destination="dZP-fH-9sg" id="iCn-VY-P3p"/> - <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="switchCanChange" destination="0yc-df-C1f" id="JcH-18-ZRX"/> - <outlet property="switchCanCreate" destination="1br-PL-gFf" id="3En-bH-Wzm"/> - <outlet property="switchCanDelete" destination="vja-ge-I6S" id="NN7-2l-NSz"/> - <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="1.875" y="195"/> - </view> - </objects> - <resources> - <image name="file_txt" width="300" height="300"/> - <image name="trash" width="512" height="512"/> - </resources> -</document> diff --git a/iOSClient/Share/NCShareUserMenuView.swift b/iOSClient/Share/NCShareUserMenuView.swift deleted file mode 100644 index 9dd2c2be2..000000000 --- a/iOSClient/Share/NCShareUserMenuView.swift +++ /dev/null @@ -1,398 +0,0 @@ -// -// 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 UIKit -import FSCalendar -import NCCommunication - -class NCShareUserMenuView: UIView, UIGestureRecognizerDelegate, UITextFieldDelegate, NCShareNetworkingDelegate, FSCalendarDelegate, FSCalendarDelegateAppearance { - - @IBOutlet weak var switchCanReshare: UISwitch! - @IBOutlet weak var labelCanReshare: UILabel! - - @IBOutlet weak var switchCanCreate: UISwitch! - @IBOutlet weak var labelCanCreate: UILabel! - - @IBOutlet weak var switchCanChange: UISwitch! - @IBOutlet weak var labelCanChange: UILabel! - - @IBOutlet weak var switchCanDelete: UISwitch! - @IBOutlet weak var labelCanDelete: 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 - - var width: CGFloat = 0 - var height: CGFloat = 0 - - private var tableShare: tableShare? - var metadata: tableMetadata? - var shareViewController: NCShare? - private var networking: NCShareNetworking? - - var viewWindow: UIView? - var viewWindowCalendar: UIView? - private var calendar: FSCalendar? - private var activeTextfieldDiff: CGFloat = 0 - private var activeTextField = UITextField() - - override func awakeFromNib() { - - 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.shared.brandElement - switchCanCreate?.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) - switchCanCreate?.onTintColor = NCBrandColor.shared.brandElement - switchCanChange?.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) - switchCanChange?.onTintColor = NCBrandColor.shared.brandElement - switchCanDelete?.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) - switchCanDelete?.onTintColor = NCBrandColor.shared.brandElement - switchSetExpirationDate.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) - switchSetExpirationDate.onTintColor = NCBrandColor.shared.brandElement - - labelCanReshare?.text = NSLocalizedString("_share_can_reshare_", comment: "") - labelCanReshare?.textColor = NCBrandColor.shared.label - labelCanCreate?.text = NSLocalizedString("_share_can_create_", comment: "") - labelCanCreate?.textColor = NCBrandColor.shared.label - labelCanChange?.text = NSLocalizedString("_share_can_change_", comment: "") - labelCanChange?.textColor = NCBrandColor.shared.label - labelCanDelete?.text = NSLocalizedString("_share_can_delete_", comment: "") - labelCanDelete?.textColor = NCBrandColor.shared.label - labelSetExpirationDate?.text = NSLocalizedString("_share_expiration_date_", comment: "") - labelSetExpirationDate?.textColor = NCBrandColor.shared.label - labelNoteToRecipient?.text = NSLocalizedString("_share_note_recipient_", comment: "") - labelNoteToRecipient?.textColor = NCBrandColor.shared.label - labelUnshare?.text = NSLocalizedString("_share_unshare_", comment: "") - labelUnshare?.textColor = NCBrandColor.shared.label - - fieldSetExpirationDate.inputView = UIView() - - fieldNoteToRecipient.delegate = self - - imageNoteToRecipient.image = UIImage(named: "file_txt")!.image(color: NCBrandColor.shared.gray, size: 50) - imageUnshare.image = NCUtility.shared.loadImage(named: "trash", color: NCBrandColor.shared.gray, size: 50) - - NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) - } - - override func willMove(toWindow newWindow: UIWindow?) { - super.willMove(toWindow: newWindow) - - if newWindow == nil { - // UIView disappear - shareViewController?.reloadData() - } else { - // UIView appear - networking = NCShareNetworking(metadata: metadata!, urlBase: appDelegate.urlBase, view: self, delegate: self) - } - } - - func unLoad() { - viewWindowCalendar?.removeFromSuperview() - viewWindow?.removeFromSuperview() - - viewWindowCalendar = nil - viewWindow = nil - } - - func reloadData(idShare: Int) { - - guard let metadata = self.metadata else { return } - tableShare = NCManageDatabase.shared.getTableShare(account: metadata.account, idShare: idShare) - guard let tableShare = self.tableShare else { return } - - // Can reshare (file) - let canReshare = CCUtility.isPermission(toCanShare: tableShare.permissions) - switchCanReshare.setOn(canReshare, animated: false) - - if metadata.directory { - // Can create (folder) - let canCreate = CCUtility.isPermission(toCanCreate: tableShare.permissions) - switchCanCreate.setOn(canCreate, animated: false) - - // Can change (folder) - let canChange = CCUtility.isPermission(toCanChange: tableShare.permissions) - switchCanChange.setOn(canChange, animated: false) - - // Can delete (folder) - let canDelete = CCUtility.isPermission(toCanDelete: tableShare.permissions) - switchCanDelete.setOn(canDelete, animated: false) - } - - // Set expiration date - if 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 - fieldNoteToRecipient.text = tableShare.note - } - - func textFieldDidBeginEditing(_ textField: UITextField) { - - self.activeTextField = textField - } - - // MARK: - Keyboard notification - - @objc internal func keyboardWillShow(_ notification: Notification?) { - - activeTextfieldDiff = 0 - - if let info = notification?.userInfo, let centerObject = self.activeTextField.superview?.convert(self.activeTextField.center, to: nil) { - - let frameEndUserInfoKey = UIResponder.keyboardFrameEndUserInfoKey - if let keyboardFrame = info[frameEndUserInfoKey] as? CGRect { - let diff = keyboardFrame.origin.y - centerObject.y - self.activeTextField.frame.height - if diff < 0 { - activeTextfieldDiff = diff - self.frame.origin.y += diff - } - } - } - } - - @objc func keyboardWillHide(_ notification: Notification) { - self.frame.origin.y -= activeTextfieldDiff - } - - // MARK: - Tap viewWindowCalendar - - @objc func tapViewWindowCalendar(gesture: UITapGestureRecognizer) { - calendar?.removeFromSuperview() - viewWindowCalendar?.removeFromSuperview() - - calendar = nil - viewWindowCalendar = nil - - reloadData(idShare: tableShare?.idShare ?? 0) - } - - func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { - return gestureRecognizer.view == touch.view - } - - // MARK: - IBAction - - // Can reshare - @IBAction func switchCanReshareChanged(sender: UISwitch) { - - guard let tableShare = self.tableShare else { return } - guard let metadata = self.metadata else { return } - - let canEdit = CCUtility.isAnyPermission(toEdit: tableShare.permissions) - let canCreate = CCUtility.isPermission(toCanCreate: tableShare.permissions) - let canChange = CCUtility.isPermission(toCanChange: tableShare.permissions) - let canDelete = CCUtility.isPermission(toCanDelete: tableShare.permissions) - - var permissions: Int = 0 - - if metadata.directory { - permissions = CCUtility.getPermissionsValue(byCanEdit: canEdit, andCanCreate: canCreate, andCanChange: canChange, andCanDelete: canDelete, andCanShare: sender.isOn, andIsFolder: metadata.directory) - } else { - if sender.isOn { - if canEdit { - permissions = CCUtility.getPermissionsValue(byCanEdit: true, andCanCreate: true, andCanChange: true, andCanDelete: true, andCanShare: sender.isOn, andIsFolder: metadata.directory) - } else { - permissions = CCUtility.getPermissionsValue(byCanEdit: false, andCanCreate: false, andCanChange: false, andCanDelete: false, andCanShare: sender.isOn, andIsFolder: metadata.directory) - } - } else { - if canEdit { - permissions = CCUtility.getPermissionsValue(byCanEdit: true, andCanCreate: true, andCanChange: true, andCanDelete: true, andCanShare: sender.isOn, andIsFolder: metadata.directory) - } else { - permissions = CCUtility.getPermissionsValue(byCanEdit: false, andCanCreate: false, andCanChange: false, andCanDelete: false, andCanShare: sender.isOn, andIsFolder: metadata.directory) - } - } - } - - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: permissions, note: nil, label: nil, expirationDate: nil, hideDownload: tableShare.hideDownload) - } - - @IBAction func switchCanCreate(sender: UISwitch) { - - guard let tableShare = self.tableShare else { return } - guard let metadata = self.metadata else { return } - - let canEdit = CCUtility.isAnyPermission(toEdit: tableShare.permissions) - let canChange = CCUtility.isPermission(toCanChange: tableShare.permissions) - let canDelete = CCUtility.isPermission(toCanDelete: tableShare.permissions) - let canShare = CCUtility.isPermission(toCanShare: tableShare.permissions) - - let permissions = CCUtility.getPermissionsValue(byCanEdit: canEdit, andCanCreate: sender.isOn, andCanChange: canChange, andCanDelete: canDelete, andCanShare: canShare, andIsFolder: metadata.directory) - - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: permissions, note: nil, label: nil, expirationDate: nil, hideDownload: tableShare.hideDownload) - } - - @IBAction func switchCanChange(sender: UISwitch) { - - guard let tableShare = self.tableShare else { return } - guard let metadata = self.metadata else { return } - - let canEdit = CCUtility.isAnyPermission(toEdit: tableShare.permissions) - let canCreate = CCUtility.isPermission(toCanCreate: tableShare.permissions) - let canDelete = CCUtility.isPermission(toCanDelete: tableShare.permissions) - let canShare = CCUtility.isPermission(toCanShare: tableShare.permissions) - - let permissions = CCUtility.getPermissionsValue(byCanEdit: canEdit, andCanCreate: canCreate, andCanChange: sender.isOn, andCanDelete: canDelete, andCanShare: canShare, andIsFolder: metadata.directory) - - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: permissions, note: nil, label: nil, expirationDate: nil, hideDownload: tableShare.hideDownload) - } - - @IBAction func switchCanDelete(sender: UISwitch) { - - guard let tableShare = self.tableShare else { return } - guard let metadata = self.metadata else { return } - - let canEdit = CCUtility.isAnyPermission(toEdit: tableShare.permissions) - let canCreate = CCUtility.isPermission(toCanCreate: tableShare.permissions) - let canChange = CCUtility.isPermission(toCanChange: tableShare.permissions) - let canShare = CCUtility.isPermission(toCanShare: tableShare.permissions) - - let permissions = CCUtility.getPermissionsValue(byCanEdit: canEdit, andCanCreate: canCreate, andCanChange: canChange, andCanDelete: sender.isOn, andCanShare: canShare, andIsFolder: metadata.directory) - - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: permissions, note: nil, label: nil, expirationDate: 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 { - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: tableShare.permissions, note: nil, label: nil, expirationDate: "", hideDownload: tableShare.hideDownload) - } - } - - @IBAction func fieldSetExpirationDate(sender: UITextField) { - - let calendar = NCShareCommon.shared.openCalendar(view: self, width: width, height: height) - calendar.calendarView.delegate = self - self.calendar = calendar.calendarView - viewWindowCalendar = calendar.viewWindow - - let tap = UITapGestureRecognizer(target: self, action: #selector(tapViewWindowCalendar)) - tap.delegate = self - viewWindowCalendar?.addGestureRecognizer(tap) - } - - // Note to recipient - @IBAction func fieldNoteToRecipientDidEndOnExit(textField: UITextField) { - - guard let tableShare = self.tableShare else { return } - if fieldNoteToRecipient.text == nil { return } - - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: tableShare.permissions, note: fieldNoteToRecipient.text, label: nil, expirationDate: nil, hideDownload: tableShare.hideDownload) - } - - // Unshare - @IBAction func buttonUnshare(sender: UIButton) { - - guard let tableShare = self.tableShare else { return } - - networking?.unShare(idShare: tableShare.idShare) - } - - // MARK: - Delegate networking - - func readShareCompleted() { - reloadData(idShare: tableShare?.idShare ?? 0) - } - - func shareCompleted() { - unLoad() - NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataNCShare) - } - - func unShareCompleted() { - unLoad() - NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataNCShare) - } - - func updateShareWithError(idShare: Int) { - reloadData(idShare: idShare) - } - - func getSharees(sharees: [NCCommunicationSharee]?) { } - - // MARK: - Delegate 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 } - - dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss" - let expirationDate = dateFormatter.string(from: date) - - networking?.updateShare(idShare: tableShare.idShare, password: nil, permissions: tableShare.permissions, note: nil, label: nil, expirationDate: expirationDate, 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? { - return date > Date() ? NCBrandColor.shared.label : NCBrandColor.shared.systemGray3 - } -} diff --git a/iOSClient/Share/NCShareUserMenuView.xib b/iOSClient/Share/NCShareUserMenuView.xib deleted file mode 100644 index 38a4304ad..000000000 --- a/iOSClient/Share/NCShareUserMenuView.xib +++ /dev/null @@ -1,160 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES"> - <device id="retina3_5" orientation="portrait" appearance="light"/> - <dependencies> - <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/> - <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="250" height="270"/> - <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"/> - <connections> - <action selector="switchCanReshareChangedWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="Ezn-AP-uEh"/> - </connections> - </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="170" 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"/> - <connections> - <action selector="switchSetExpirationDateWithSender:" destination="iN0-l3-epB" eventType="valueChanged" id="A9c-YF-bXd"/> - </connections> - </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="170" 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="170" height="30"/> - <constraints> - <constraint firstAttribute="height" constant="30" id="G4f-LN-v7k"/> - </constraints> - <fontDescription key="fontDescription" type="system" pointSize="13"/> - <textInputTraits key="textInputTraits"/> - <connections> - <action selector="fieldSetExpirationDateWithSender:" destination="iN0-l3-epB" eventType="editingDidEndOnExit" id="WdF-Ie-Di0"/> - </connections> - </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="175" 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="170" height="34"/> - <fontDescription key="fontDescription" type="system" pointSize="14"/> - <textInputTraits key="textInputTraits"/> - <connections> - <action selector="fieldNoteToRecipientDidEndOnExitWithTextField:" destination="iN0-l3-epB" eventType="editingDidEndOnExit" id="q1P-u7-EBw"/> - </connections> - </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="228" 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="233" width="170" 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="228" width="217" height="25"/> - <constraints> - <constraint firstAttribute="height" constant="25" id="fWP-XF-kQx"/> - </constraints> - <connections> - <action selector="buttonUnshareWithSender:" destination="iN0-l3-epB" eventType="touchUpInside" id="Nky-nT-rCz"/> - </connections> - </button> - </subviews> - <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="bottom" relation="greaterThanOrEqual" secondItem="CLA-UL-mYb" secondAttribute="bottom" constant="10" id="MQ9-xT-wSR"/> - <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> - <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> - <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="512" height="512"/> - </resources> -</document> diff --git a/iOSClient/Supporting Files/en.lproj/Localizable.strings b/iOSClient/Supporting Files/en.lproj/Localizable.strings index 70f0c802e..0709a71d9 100644 --- a/iOSClient/Supporting Files/en.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/en.lproj/Localizable.strings @@ -22,6 +22,7 @@ "_cancel_" = "Cancel"; "_tap_to_cancel_" = "Tap to cancel"; +"_cancel_request_" = "Do you want to cancel?"; "_upload_file_" = "Upload file"; "_accessibility_add_upload_" = "Add and upload"; "_download_file_" = "Download file"; @@ -62,6 +63,7 @@ "_beta_version_" = "Beta version"; "_function_in_testing_" = "Function in testing, please send information about any problems you run into."; "_done_" = "Done"; +"_clear_" = "Clear"; "_passcode_too_short_" = "Passcode too short, at least 4 characters required"; "_selected_" = "Selected"; "_scan_fingerprint_" = "Scan fingerprint to authenticate"; @@ -81,6 +83,7 @@ "_remove_" = "Remove"; "_file_not_found_" = "File not found"; "_continue_" = "Continue"; +"_continue_editing_" = "Continue editing"; "_continue_request_" = "Do you want to continue?"; "_auto_upload_folder_" = "Auto upload"; "_gallery_" = "Gallery"; @@ -336,6 +339,7 @@ "_user_editprofile_" = "Edit profile"; "_select_offline_warning_" = "Making multiple files and folders available offline may take a while and use a lot of memory while doing so."; "_advanced_" = "Advanced"; +"_permissions_" = "Permissions"; "_disable_files_app_" = "Disable Files App integration"; "_disable_files_app_footer_" = "Do not permit the access of files via the iOS Files application"; "_trial_" = "Trial"; @@ -564,7 +568,7 @@ "_error_download_photobrowser_" = "Error: Unable to download photo"; "_share_link_" = "Share link"; "_share_link_button_" = "Send link to …"; -"_Link_name_" = "Link name"; +"_share_link_name_" = "Link name"; "_password_" = "Password"; "_share_password_" = "Password protected link"; "_share_expirationdate_" = "Set expiration date for link"; @@ -609,6 +613,9 @@ "_share_unshare_" = "Unshare"; "_share_internal_link_" = "Internal link"; "_share_internal_link_des_" = "Only works for users with access to this folder"; +"_share_reshare_disabled_" = "You are not allowed to reshare this file / folder"; +"_share_reshare_restricted_" = "Note: You only have limited prmission to reshare this file / folder"; + "_no_transfer_" = "No transfers yet"; "_no_transfer_sub_" = "Uploads and downloads from this device will show up here"; "_no_activity_" = "No activity yet"; @@ -804,6 +811,7 @@ "_save_as_copy_" = "Save as copy"; "_discard_changes_" = "Close and discard changes"; "_message_disable_overwrite_livephoto_" = "This image is a Live Photo, overwrite will not be possible"; +"_discard_changes_info_" = "Your changes will be discarded."; "_delete_files_desc_" = "Delete files to free up space"; "_delete_old_files_" = "Delete all files older than"; "_never_" = "Never"; diff --git a/iOSClient/Supporting Files/eu.lproj/Localizable.strings b/iOSClient/Supporting Files/eu.lproj/Localizable.strings Binary files differindex 500f7ab5a..05ea90f1a 100644 --- a/iOSClient/Supporting Files/eu.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/eu.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/zh_HK.lproj/Localizable.strings b/iOSClient/Supporting Files/zh_HK.lproj/Localizable.strings Binary files differindex 7dfd2174b..359724758 100644 --- a/iOSClient/Supporting Files/zh_HK.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/zh_HK.lproj/Localizable.strings diff --git a/iOSClient/Utility/NCUtility+Image.swift b/iOSClient/Utility/NCUtility+Image.swift new file mode 100644 index 000000000..a56f96e91 --- /dev/null +++ b/iOSClient/Utility/NCUtility+Image.swift @@ -0,0 +1,91 @@ +// +// NCUtility+Image.swift +// Nextcloud +// +// Created by Henrik Storch on 17.03.22. +// Copyright © 2022 Henrik Storch. All rights reserved. +// +// Author Henrik Storch <henrik.storch@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 UIKit +import SVGKit +import NCCommunication + +extension NCUtility { + func getImageMetadata(_ metadata: tableMetadata, for size: CGFloat) -> UIImage? { + + if let image = getImage(metadata: metadata) { + return image + } + + if metadata.classFile == NCCommunicationCommon.typeClassFile.video.rawValue && !metadata.hasPreview { + NCUtility.shared.createImageFrom(fileName: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, classFile: metadata.classFile) + } + + if CCUtility.fileProviderStoragePreviewIconExists(metadata.ocId, etag: metadata.etag) { + if let imagePreviewPath = CCUtility.getDirectoryProviderStoragePreviewOcId(metadata.ocId, etag: metadata.etag) { + return UIImage(contentsOfFile: imagePreviewPath) + } + } + + if metadata.classFile == NCCommunicationCommon.typeClassFile.video.rawValue { + return UIImage(named: "noPreviewVideo")?.image(color: .gray, size: size) + } else if metadata.classFile == NCCommunicationCommon.typeClassFile.audio.rawValue { + return UIImage(named: "noPreviewAudio")?.image(color: .gray, size: size) + } else { + return UIImage(named: "noPreview")?.image(color: .gray, size: size) + } + } + + func getImage(metadata: tableMetadata) -> UIImage? { + let ext = CCUtility.getExtension(metadata.fileNameView) + var image: UIImage? + + if CCUtility.fileProviderStorageExists(metadata) && metadata.classFile == NCCommunicationCommon.typeClassFile.image.rawValue { + + let previewPath = CCUtility.getDirectoryProviderStoragePreviewOcId(metadata.ocId, etag: metadata.etag)! + let imagePath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)! + + if ext == "GIF" { + if !FileManager().fileExists(atPath: previewPath) { + NCUtility.shared.createImageFrom(fileName: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, classFile: metadata.classFile) + } + image = UIImage.animatedImage(withAnimatedGIFURL: URL(fileURLWithPath: imagePath)) + } else if ext == "SVG" { + if let svgImage = SVGKImage(contentsOfFile: imagePath) { + svgImage.size = CGSize(width: NCGlobal.shared.sizePreview, height: NCGlobal.shared.sizePreview) + if let image = svgImage.uiImage { + if !FileManager().fileExists(atPath: previewPath) { + do { + try image.pngData()?.write(to: URL(fileURLWithPath: previewPath), options: .atomic) + } catch { } + } + return image + } else { + return nil + } + } else { + return nil + } + } else { + NCUtility.shared.createImageFrom(fileName: metadata.fileNameView, ocId: metadata.ocId, etag: metadata.etag, classFile: metadata.classFile) + image = UIImage(contentsOfFile: imagePath) + } + } + return image + } +} |