Browse Source

Merge branch 'develop'

marinofaggiana 6 years ago
parent
commit
c069a9c33c
100 changed files with 1157 additions and 480 deletions
  1. 1 0
      Cartfile
  2. 2 1
      Cartfile.resolved
  3. 33 0
      Nextcloud.xcodeproj/project.pbxproj
  4. 221 199
      iOSClient/Activity/NCActivity.swift
  5. 1 0
      iOSClient/AppDelegate.h
  6. 15 3
      iOSClient/AppDelegate.m
  7. 118 0
      iOSClient/AudioRecorder/NCAudioRecorderViewController.storyboard
  8. 307 0
      iOSClient/AudioRecorder/NCAudioRecorderViewController.swift
  9. 1 1
      iOSClient/Brand/File_Provider_Extension.plist
  10. 2 3
      iOSClient/Brand/NCBrand.swift
  11. 1 1
      iOSClient/Brand/Notification_Service_Extension.plist
  12. 1 1
      iOSClient/Brand/Share.plist
  13. 1 1
      iOSClient/Brand/iOSClient.plist
  14. 24 0
      iOSClient/Database/NCDatabase.swift
  15. 69 32
      iOSClient/Database/NCManageDatabase.swift
  16. 1 2
      iOSClient/Favorites/CCFavorites.h
  17. 44 40
      iOSClient/Favorites/CCFavorites.m
  18. 1 12
      iOSClient/Images.xcassets/acknowledgements.imageset/Contents.json
  19. BIN
      iOSClient/Images.xcassets/acknowledgements.imageset/acknowledgements.pdf
  20. BIN
      iOSClient/Images.xcassets/acknowledgements.imageset/acknowledgements.png
  21. BIN
      iOSClient/Images.xcassets/acknowledgements.imageset/acknowledgements@2x.png
  22. BIN
      iOSClient/Images.xcassets/acknowledgements.imageset/acknowledgements@3x.png
  23. 4 12
      iOSClient/Images.xcassets/activity.imageset/Contents.json
  24. BIN
      iOSClient/Images.xcassets/activity.imageset/activity.pdf
  25. BIN
      iOSClient/Images.xcassets/activity.imageset/activity.png
  26. BIN
      iOSClient/Images.xcassets/activity.imageset/activity@2x.png
  27. BIN
      iOSClient/Images.xcassets/activity.imageset/activity@3x.png
  28. BIN
      iOSClient/Images.xcassets/activityNoRecord.imageset/activityNoRecord@2x.png
  29. 15 0
      iOSClient/Images.xcassets/audioPlay.imageset/Contents.json
  30. BIN
      iOSClient/Images.xcassets/audioPlay.imageset/play.pdf
  31. 15 0
      iOSClient/Images.xcassets/audioStop.imageset/Contents.json
  32. BIN
      iOSClient/Images.xcassets/audioStop.imageset/stop.pdf
  33. 4 12
      iOSClient/Images.xcassets/autoUpload.imageset/Contents.json
  34. BIN
      iOSClient/Images.xcassets/autoUpload.imageset/autoUpload.pdf
  35. BIN
      iOSClient/Images.xcassets/autoUpload.imageset/autoUpload.png
  36. BIN
      iOSClient/Images.xcassets/autoUpload.imageset/autoUpload@2x.png
  37. BIN
      iOSClient/Images.xcassets/autoUpload.imageset/autoUpload@3x.png
  38. 0 21
      iOSClient/Images.xcassets/button1000x200.imageset/Contents.json
  39. BIN
      iOSClient/Images.xcassets/button1000x200.imageset/button1000x200@2x.png
  40. 0 21
      iOSClient/Images.xcassets/button500x100.imageset/Contents.json
  41. BIN
      iOSClient/Images.xcassets/button500x100.imageset/button500x100@2x.png
  42. 15 0
      iOSClient/Images.xcassets/cancel.imageset/Contents.json
  43. BIN
      iOSClient/Images.xcassets/cancel.imageset/cancel.pdf
  44. 4 12
      iOSClient/Images.xcassets/checkedNo.imageset/Contents.json
  45. BIN
      iOSClient/Images.xcassets/checkedNo.imageset/checkedNo.pdf
  46. BIN
      iOSClient/Images.xcassets/checkedNo.imageset/checkedNo.png
  47. BIN
      iOSClient/Images.xcassets/checkedNo.imageset/checkedNo@2x.png
  48. BIN
      iOSClient/Images.xcassets/checkedNo.imageset/checkedNo@3x.png
  49. 1 12
      iOSClient/Images.xcassets/checkedYes.imageset/Contents.json
  50. BIN
      iOSClient/Images.xcassets/checkedYes.imageset/checkedYes.pdf
  51. BIN
      iOSClient/Images.xcassets/checkedYes.imageset/checkedYes.png
  52. BIN
      iOSClient/Images.xcassets/checkedYes.imageset/checkedYes@2x.png
  53. BIN
      iOSClient/Images.xcassets/checkedYes.imageset/checkedYes@3x.png
  54. 15 0
      iOSClient/Images.xcassets/closeCircle.imageset/Contents.json
  55. 51 0
      iOSClient/Images.xcassets/closeCircle.imageset/closeCircle.pdf
  56. 1 1
      iOSClient/Images.xcassets/create_file_document.imageset/Contents.json
  57. 0 0
      iOSClient/Images.xcassets/create_file_document.imageset/create_file_document@2x.png
  58. 0 0
      iOSClient/Images.xcassets/create_file_document.imageset/document_menu.png
  59. 0 0
      iOSClient/Images.xcassets/create_file_document.imageset/document_menu@3x.png
  60. 1 1
      iOSClient/Images.xcassets/create_file_ppt.imageset/Contents.json
  61. 0 0
      iOSClient/Images.xcassets/create_file_ppt.imageset/create_file_ppt@2x.png
  62. 0 0
      iOSClient/Images.xcassets/create_file_ppt.imageset/file_ppt_menu.png
  63. 0 0
      iOSClient/Images.xcassets/create_file_ppt.imageset/file_ppt_menu@3x.png
  64. 1 1
      iOSClient/Images.xcassets/create_file_xls.imageset/Contents.json
  65. 0 0
      iOSClient/Images.xcassets/create_file_xls.imageset/create_file_xls@2x.png
  66. 0 0
      iOSClient/Images.xcassets/create_file_xls.imageset/file_xls_menu.png
  67. 0 0
      iOSClient/Images.xcassets/create_file_xls.imageset/file_xls_menu@3x.png
  68. 0 0
      iOSClient/Images.xcassets/deletePhotoBrowser.imageset/Contents.json
  69. 0 0
      iOSClient/Images.xcassets/deletePhotoBrowser.imageset/delete.png
  70. 0 0
      iOSClient/Images.xcassets/deletePhotoBrowser.imageset/delete@2x.png
  71. 0 0
      iOSClient/Images.xcassets/deletePhotoBrowser.imageset/delete@3x.png
  72. 15 0
      iOSClient/Images.xcassets/details.imageset/Contents.json
  73. BIN
      iOSClient/Images.xcassets/details.imageset/details.pdf
  74. 1 10
      iOSClient/Images.xcassets/disclosureIndicator.imageset/Contents.json
  75. 4 12
      iOSClient/Images.xcassets/document.imageset/Contents.json
  76. 52 0
      iOSClient/Images.xcassets/document.imageset/document.pdf
  77. BIN
      iOSClient/Images.xcassets/document.imageset/document@2x.png
  78. BIN
      iOSClient/Images.xcassets/document.imageset/document@3x.png
  79. BIN
      iOSClient/Images.xcassets/document_menu.imageset/document_menu@2x.png
  80. 4 12
      iOSClient/Images.xcassets/e2eReadPassphrase.imageset/Contents.json
  81. BIN
      iOSClient/Images.xcassets/e2eReadPassphrase.imageset/e2eReadPassphrase.pdf
  82. BIN
      iOSClient/Images.xcassets/e2eReadPassphrase.imageset/e2eReadPassphrase.png
  83. BIN
      iOSClient/Images.xcassets/e2eReadPassphrase.imageset/e2eReadPassphrase@2x.png
  84. BIN
      iOSClient/Images.xcassets/e2eReadPassphrase.imageset/e2eReadPassphrase@3x.png
  85. 4 12
      iOSClient/Images.xcassets/exit.imageset/Contents.json
  86. 51 0
      iOSClient/Images.xcassets/exit.imageset/exit.pdf
  87. BIN
      iOSClient/Images.xcassets/exit.imageset/exit.png
  88. BIN
      iOSClient/Images.xcassets/exit.imageset/exit@2x.png
  89. BIN
      iOSClient/Images.xcassets/exit.imageset/exit@3x.png
  90. 1 12
      iOSClient/Images.xcassets/favorite.imageset/Contents.json
  91. BIN
      iOSClient/Images.xcassets/favorite.imageset/favorite.pdf
  92. BIN
      iOSClient/Images.xcassets/favorite.imageset/favorite.png
  93. BIN
      iOSClient/Images.xcassets/favorite.imageset/favorite@2x.png
  94. BIN
      iOSClient/Images.xcassets/favorite.imageset/favorite@3x.png
  95. 0 21
      iOSClient/Images.xcassets/favoriteNoFiles.imageset/Contents.json
  96. BIN
      iOSClient/Images.xcassets/favoriteNoFiles.imageset/favoriteNoFiles@2x.png
  97. 4 12
      iOSClient/Images.xcassets/file.imageset/Contents.json
  98. 51 0
      iOSClient/Images.xcassets/file.imageset/file.pdf
  99. BIN
      iOSClient/Images.xcassets/file.imageset/file.png
  100. BIN
      iOSClient/Images.xcassets/file.imageset/file@2x.png

+ 1 - 0
Cartfile

@@ -13,3 +13,4 @@ github "SVGKit/SVGKit" "2.x"
 github "WeTransfer/WeScan" == 0.9.1
 github "malcommac/SwiftRichString"
 github "https://github.com/marinofaggiana/FastScroll" "master"
+github "yannickl/QRCodeReader.swift" >= 10.0.0

+ 2 - 1
Cartfile.resolved

@@ -11,7 +11,8 @@ github "ealeksandrov/EARestrictedScrollView" "1.1.0"
 github "jdg/MBProgressHUD" "1.1.0"
 github "kishikawakatsumi/UICKeyChainStore" "v2.1.2"
 github "malcommac/SwiftRichString" "2.1.0"
-github "marinofaggiana/FastScroll" "f52a16b20e738ee669658fa448016601a7494424"
+github "marinofaggiana/FastScroll" "81967c2309d29bc2c330d422da612160a30bade8"
 github "realm/realm-cocoa" "v3.13.1"
 github "sgr-ksmt/PDFGenerator" "2.1.1"
 github "tilltue/TLPhotoPicker" "1.8.3"
+github "yannickl/QRCodeReader.swift" "10.0.0"

+ 33 - 0
Nextcloud.xcodeproj/project.pbxproj

@@ -65,6 +65,7 @@
 		F70022FC1EC4C9100080073F /* NSString+Encode.m in Sources */ = {isa = PBXBuildFile; fileRef = F700229D1EC4C9100080073F /* NSString+Encode.m */; };
 		F70022FE1EC4C9100080073F /* UtilsFramework.m in Sources */ = {isa = PBXBuildFile; fileRef = F70022A01EC4C9100080073F /* UtilsFramework.m */; };
 		F70022FF1EC4C9100080073F /* UtilsFramework.m in Sources */ = {isa = PBXBuildFile; fileRef = F70022A01EC4C9100080073F /* UtilsFramework.m */; };
+		F7020FCE2233D7F700B7297D /* NCCreateFormUploadVoiceNote.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7020FCD2233D7F700B7297D /* NCCreateFormUploadVoiceNote.swift */; };
 		F7063DED2199E55F003F38DA /* SVGKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7063DEC2199E55F003F38DA /* SVGKit.framework */; };
 		F7063DEF2199E568003F38DA /* CocoaLumberjack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7063DEE2199E568003F38DA /* CocoaLumberjack.framework */; };
 		F7063DF12199E56F003F38DA /* CocoaLumberjackSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7063DF02199E56E003F38DA /* CocoaLumberjackSwift.framework */; };
@@ -239,6 +240,9 @@
 		F7434B6120E2445C00417916 /* CCCertificate.m in Sources */ = {isa = PBXBuildFile; fileRef = F7F801011D98205A007537BC /* CCCertificate.m */; };
 		F7434B6220E249F700417916 /* NSNotificationCenter+MainThread.m in Sources */ = {isa = PBXBuildFile; fileRef = F78071081EDAB65800EAFFF6 /* NSNotificationCenter+MainThread.m */; };
 		F7434B6320E249FB00417916 /* NSString+TruncateToWidth.m in Sources */ = {isa = PBXBuildFile; fileRef = F73049B91CB567F000C7C320 /* NSString+TruncateToWidth.m */; };
+		F745B251222D871800346520 /* QRCodeReader.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F745B250222D871800346520 /* QRCodeReader.framework */; };
+		F745B253222D88AE00346520 /* NCLoginQRCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = F745B252222D88AE00346520 /* NCLoginQRCode.swift */; };
+		F747BA1F22354D2000971601 /* NCCreateFormUploadVoiceNote.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F747BA1E22354D2000971601 /* NCCreateFormUploadVoiceNote.storyboard */; };
 		F749E4E91DC1FB38009BA2FD /* Share.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = F7CE8AFB1DC1F8D8009CAE48 /* Share.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
 		F74E432620B5547700C2E54C /* NCNetworkingEndToEnd.m in Sources */ = {isa = PBXBuildFile; fileRef = F74E432520B5547700C2E54C /* NCNetworkingEndToEnd.m */; };
 		F74E432720B5547700C2E54C /* NCNetworkingEndToEnd.m in Sources */ = {isa = PBXBuildFile; fileRef = F74E432520B5547700C2E54C /* NCNetworkingEndToEnd.m */; };
@@ -549,6 +553,8 @@
 		F7DFB7F2219C5C0000680748 /* NCCreateFormUploadFileText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7DFB7F1219C5C0000680748 /* NCCreateFormUploadFileText.swift */; };
 		F7DFB7F4219C5CA800680748 /* NCCreateFormUploadScanDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7DFB7F3219C5CA800680748 /* NCCreateFormUploadScanDocument.swift */; };
 		F7DFB7F6219C5F2300680748 /* NCCreateFormUploadRichdocuments.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7DFB7F5219C5F2300680748 /* NCCreateFormUploadRichdocuments.storyboard */; };
+		F7E0E1DC22327885006B0911 /* NCAudioRecorderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7E0E1DB22327885006B0911 /* NCAudioRecorderViewController.swift */; };
+		F7E0E1DE22327DBA006B0911 /* NCAudioRecorderViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7E0E1DD22327DBA006B0911 /* NCAudioRecorderViewController.storyboard */; };
 		F7E9C41B20F4CA870040CF18 /* CCTransfers.m in Sources */ = {isa = PBXBuildFile; fileRef = F7E9C41820F4CA870040CF18 /* CCTransfers.m */; };
 		F7ECBA6D1E239DCD003E6328 /* NCCreateFormUploadRichdocuments.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7ECBA6C1E239DCD003E6328 /* NCCreateFormUploadRichdocuments.swift */; };
 		F7F54CE51E5B14C700E19C62 /* ImageError.png in Resources */ = {isa = PBXBuildFile; fileRef = F7F54CAF1E5B14C700E19C62 /* ImageError.png */; };
@@ -719,6 +725,7 @@
 		F700229E1EC4C9100080073F /* OCConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCConstants.h; sourceTree = "<group>"; };
 		F700229F1EC4C9100080073F /* UtilsFramework.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UtilsFramework.h; sourceTree = "<group>"; };
 		F70022A01EC4C9100080073F /* UtilsFramework.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UtilsFramework.m; sourceTree = "<group>"; };
+		F7020FCD2233D7F700B7297D /* NCCreateFormUploadVoiceNote.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCCreateFormUploadVoiceNote.swift; sourceTree = "<group>"; };
 		F70211F51BAC56E9003FC03E /* CCCellMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCCellMain.m; sourceTree = "<group>"; };
 		F70211F61BAC56E9003FC03E /* CCCellMain.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CCCellMain.xib; sourceTree = "<group>"; };
 		F70211F71BAC56E9003FC03E /* CCCellMainTransfer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCCellMainTransfer.h; sourceTree = "<group>"; };
@@ -884,6 +891,9 @@
 		F7434B5F20E2440600417916 /* FileProviderExtension-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FileProviderExtension-Bridging-Header.h"; sourceTree = "<group>"; };
 		F743B2C31C95BBE8006F5B4A /* CCShareInfoCMOC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCShareInfoCMOC.h; sourceTree = "<group>"; };
 		F743B2C41C95BBE8006F5B4A /* CCShareInfoCMOC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCShareInfoCMOC.m; sourceTree = "<group>"; };
+		F745B250222D871800346520 /* QRCodeReader.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QRCodeReader.framework; path = Carthage/Build/iOS/QRCodeReader.framework; sourceTree = "<group>"; };
+		F745B252222D88AE00346520 /* NCLoginQRCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCLoginQRCode.swift; sourceTree = "<group>"; };
+		F747BA1E22354D2000971601 /* NCCreateFormUploadVoiceNote.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = NCCreateFormUploadVoiceNote.storyboard; sourceTree = "<group>"; };
 		F7496B81208F5651004B299C /* iOSClient.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = iOSClient.plist; sourceTree = "<group>"; };
 		F7496B83208F5652004B299C /* Share.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Share.plist; sourceTree = "<group>"; };
 		F74D3DBD1BAC1941000BAE4B /* OCNetworking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCNetworking.h; sourceTree = "<group>"; };
@@ -1387,6 +1397,8 @@
 		F7DFB7F1219C5C0000680748 /* NCCreateFormUploadFileText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCreateFormUploadFileText.swift; sourceTree = "<group>"; };
 		F7DFB7F3219C5CA800680748 /* NCCreateFormUploadScanDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCreateFormUploadScanDocument.swift; sourceTree = "<group>"; };
 		F7DFB7F5219C5F2300680748 /* NCCreateFormUploadRichdocuments.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCCreateFormUploadRichdocuments.storyboard; sourceTree = "<group>"; };
+		F7E0E1DB22327885006B0911 /* NCAudioRecorderViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCAudioRecorderViewController.swift; sourceTree = "<group>"; };
+		F7E0E1DD22327DBA006B0911 /* NCAudioRecorderViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCAudioRecorderViewController.storyboard; sourceTree = "<group>"; };
 		F7E45E6D21E75BF200579249 /* ja-JP */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ja-JP"; path = "ja-JP.lproj/Localizable.strings"; sourceTree = "<group>"; };
 		F7E9C41520F4CA870040CF18 /* CCTransfers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCTransfers.h; sourceTree = "<group>"; };
 		F7E9C41820F4CA870040CF18 /* CCTransfers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCTransfers.m; sourceTree = "<group>"; };
@@ -1512,6 +1524,7 @@
 				F7C40BE9219991A60004137E /* EAIntroView.framework in Frameworks */,
 				F7C40BE521998D5B0004137E /* MGSwipeTableCell.framework in Frameworks */,
 				F7C40BEB219991AC0004137E /* EARestrictedScrollView.framework in Frameworks */,
+				F745B251222D871800346520 /* QRCodeReader.framework in Frameworks */,
 				F7A3771A1EB2364A002856D3 /* Fabric.framework in Frameworks */,
 				F72E0B9D21AD60BC00898D7B /* WeScan.framework in Frameworks */,
 				F7063DED2199E55F003F38DA /* SVGKit.framework in Frameworks */,
@@ -2576,6 +2589,7 @@
 				F7BF1B3F1D51E893000854F6 /* CCLogin.h */,
 				F7BF1B401D51E893000854F6 /* CCLogin.m */,
 				F7B3A4ED1E97818A000DACE8 /* CCLoginWeb.swift */,
+				F745B252222D88AE00346520 /* NCLoginQRCode.swift */,
 			);
 			path = Login;
 			sourceTree = "<group>";
@@ -2772,6 +2786,8 @@
 				F7DFB7F5219C5F2300680748 /* NCCreateFormUploadRichdocuments.storyboard */,
 				F7ECBA6C1E239DCD003E6328 /* NCCreateFormUploadRichdocuments.swift */,
 				F7DFB7F3219C5CA800680748 /* NCCreateFormUploadScanDocument.swift */,
+				F747BA1E22354D2000971601 /* NCCreateFormUploadVoiceNote.storyboard */,
+				F7020FCD2233D7F700B7297D /* NCCreateFormUploadVoiceNote.swift */,
 				F7DFB7F1219C5C0000680748 /* NCCreateFormUploadFileText.swift */,
 				F7DFB7EF219C5B8000680748 /* NCCreateFormUploadAssets.swift */,
 				F7DFB7EA219C5A2E00680748 /* NCCreateMenuAdd.swift */,
@@ -2779,6 +2795,15 @@
 			path = "Create cloud";
 			sourceTree = "<group>";
 		};
+		F7E0E1DA22327885006B0911 /* AudioRecorder */ = {
+			isa = PBXGroup;
+			children = (
+				F7E0E1DB22327885006B0911 /* NCAudioRecorderViewController.swift */,
+				F7E0E1DD22327DBA006B0911 /* NCAudioRecorderViewController.storyboard */,
+			);
+			path = AudioRecorder;
+			sourceTree = "<group>";
+		};
 		F7E9C41320F4CA870040CF18 /* Transfers */ = {
 			isa = PBXGroup;
 			children = (
@@ -2932,6 +2957,7 @@
 				F78F74322163753B00C2ADAD /* Trash */,
 				F7E9C41320F4CA870040CF18 /* Transfers */,
 				F70784811A2C8A0D00AC9FFF /* UploadFromOtherUpp */,
+				F7E0E1DA22327885006B0911 /* AudioRecorder */,
 				F7BFFA991A24D7BB0044ED85 /* Utility */,
 			);
 			path = iOSClient;
@@ -2970,6 +2996,7 @@
 		F7FC7D541DC1F93700BB2C6A /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				F745B250222D871800346520 /* QRCodeReader.framework */,
 				F75153232226920200323DDC /* FastScroll.framework */,
 				F78AA20521F783E900D0F205 /* SwiftRichString.framework */,
 				F72E0B9C21AD60BC00898D7B /* WeScan.framework */,
@@ -3325,6 +3352,7 @@
 				F762CB981EACB84400B38484 /* icon-info@2x.png in Resources */,
 				F7D423361F0596AC009C9782 /* AppIcon-167.png in Resources */,
 				F7F54CF71E5B14C700E19C62 /* PlayButtonOverlayLargeTap.png in Resources */,
+				F7E0E1DE22327DBA006B0911 /* NCAudioRecorderViewController.storyboard in Resources */,
 				F710E8111EF95C9C00DC2427 /* ImagesIntro.xcassets in Resources */,
 				F77B0F4D1D118A16002130FE /* CCShare.storyboard in Resources */,
 				F7F54D021E5B14C700E19C62 /* UIBarButtonItemGrid@3x.png in Resources */,
@@ -3339,6 +3367,7 @@
 				F77B0F571D118A16002130FE /* synchronizedcrypto.gif in Resources */,
 				F7F54CEE1E5B14C700E19C62 /* ImageSelectedSmallOff.png in Resources */,
 				F760F79721F21F61006B1A73 /* StickerCollectionViewCell.xib in Resources */,
+				F747BA1F22354D2000971601 /* NCCreateFormUploadVoiceNote.storyboard in Resources */,
 				F73B4EF31F470D9100BBEE4B /* GB2312Freq.tab in Resources */,
 				F7B2DEF11F976859007CF4D2 /* english.txt in Resources */,
 				F7F54D051E5B14C800E19C62 /* VideoOverlay@3x.png in Resources */,
@@ -3440,6 +3469,7 @@
 				"$(SRCROOT)/Carthage/Build/iOS/WeScan.framework",
 				"$(SRCROOT)/Carthage/Build/iOS/SwiftRichString.framework",
 				"$(SRCROOT)/Carthage/Build/iOS/FastScroll.framework",
+				"$(SRCROOT)/Carthage/Build/iOS/QRCodeReader.framework",
 			);
 			outputPaths = (
 			);
@@ -3833,8 +3863,10 @@
 				F762CB151EACB66200B38484 /* XLFormRowNavigationAccessoryView.m in Sources */,
 				F762CB0A1EACB66200B38484 /* XLFormDescriptor.m in Sources */,
 				F7D4238C1F0596C6009C9782 /* UIXToolbarView.m in Sources */,
+				F7020FCE2233D7F700B7297D /* NCCreateFormUploadVoiceNote.swift in Sources */,
 				F726EEEC1FED1C820030B9C8 /* NCEndToEndInitialize.swift in Sources */,
 				F79A65C62191D95E00FF6DCC /* NCSelect.swift in Sources */,
+				F7E0E1DC22327885006B0911 /* NCAudioRecorderViewController.swift in Sources */,
 				F70CAE3A1F8CF31A008125FD /* NCEndToEndEncryption.m in Sources */,
 				F73B4F0C1F470D9100BBEE4B /* nsHebrewProber.cpp in Sources */,
 				F762CAFB1EACB66200B38484 /* XLFormDatePickerCell.m in Sources */,
@@ -3857,6 +3889,7 @@
 				F760F78E21F21F61006B1A73 /* PhotoEditor+Drawing.swift in Sources */,
 				F762CB0B1EACB66200B38484 /* XLFormRowDescriptor.m in Sources */,
 				F760F78921F21F61006B1A73 /* UIView+Image.swift in Sources */,
+				F745B253222D88AE00346520 /* NCLoginQRCode.swift in Sources */,
 				F760F79221F21F61006B1A73 /* EmojisCollectionViewDelegate.swift in Sources */,
 				F7169A1C1EE590930086BD69 /* NCShares.m in Sources */,
 				F77B0EC61D118A16002130FE /* CCCellMain.m in Sources */,

+ 221 - 199
iOSClient/Activity/NCActivity.swift

@@ -25,7 +25,7 @@ import Foundation
 import UIKit
 import SwiftRichString
 
-class NCActivity: UIViewController, UITableViewDataSource, UITableViewDelegate, UITableViewDataSourcePrefetching, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
+class NCActivity: UIViewController, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
     
     @IBOutlet weak var tableView: UITableView!
 
@@ -75,7 +75,7 @@ class NCActivity: UIViewController, UITableViewDataSource, UITableViewDelegate,
     }
     
     func image(forEmptyDataSet scrollView: UIScrollView) -> UIImage? {
-        return CCGraphics.changeThemingColorImage(UIImage.init(named: "activityNoRecord"), multiplier: 2, color: NCBrandColor.sharedInstance.graySoft)
+        return CCGraphics.changeThemingColorImage(UIImage.init(named: "activity"), width: 300, height: 300, color: NCBrandColor.sharedInstance.graySoft)
     }
     
     func title(forEmptyDataSet scrollView: UIScrollView) -> NSAttributedString? {
@@ -87,47 +87,48 @@ class NCActivity: UIViewController, UITableViewDataSource, UITableViewDelegate,
     func emptyDataSetShouldAllowScroll(_ scrollView: UIScrollView) -> Bool {
         return true
     }
+}
+
+class activityTableViewCell: UITableViewCell {
     
-    // MARK: TableView
+    private let appDelegate = UIApplication.shared.delegate as! AppDelegate
 
-    func loadDataSource() {
-        
-        sectionDate.removeAll()
+    @IBOutlet weak var collectionView: UICollectionView!
     
-        activities = NCManageDatabase.sharedInstance.getActivity(predicate: NSPredicate(format: "account == %@", appDelegate.activeAccount))
-        for tableActivity in activities {
-            guard let date = Calendar.current.date(from: Calendar.current.dateComponents([.year, .month, .day], from: tableActivity.date as Date)) else {
-                continue
-            }
-            if !sectionDate.contains(date) {
-                sectionDate.append(date)
-            }
-        }
-        tableView.reloadData()
-    }
+    @IBOutlet weak var icon: UIImageView!
+    @IBOutlet weak var avatar: UIImageView!
+    @IBOutlet weak var subject: UILabel!
+    @IBOutlet weak var subjectTrailingConstraint: NSLayoutConstraint!
+    @IBOutlet weak var collectionViewHeightConstraint: NSLayoutConstraint!
+
+    var idActivity: Int = 0
+    var account: String = ""
+    var activityPreviews = [tableActivityPreview]()
     
-    func getTableActivitiesFromSection(_ section: Int) -> [tableActivity] {
-        let startDate = sectionDate[section]
-        let endDate: Date = {
-            let components = DateComponents(day: 1, second: -1)
-            return Calendar.current.date(byAdding: components, to: startDate)!
-        }()
+    override func awakeFromNib() {
+        super.awakeFromNib()
         
-        return NCManageDatabase.sharedInstance.getActivity(predicate: NSPredicate(format: "account == %@ && date BETWEEN %@", appDelegate.activeAccount, [startDate, endDate]))
-    }
-    
-    func numberOfSections(in tableView: UITableView) -> Int {
-        return sectionDate.count
+        collectionView.delegate = self
+        collectionView.dataSource = self
     }
+}
+
+// MARK: - Table View
+
+extension NCActivity: UITableViewDelegate {
     
-    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
-        return getTableActivitiesFromSection(section).count
+    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
+        return 120
     }
     
     func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
         return 60
     }
     
+    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+        return UITableView.automaticDimension
+    }
+    
     func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
         
         let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.width, height: 60))
@@ -148,33 +149,16 @@ class NCActivity: UIViewController, UITableViewDataSource, UITableViewDelegate,
         view.addSubview(label)
         return view
     }
+}
 
-    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
-        return 120
-    }
-    
-    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
-        return UITableView.automaticDimension
-    }
+extension NCActivity: UITableViewDataSource {
     
-    func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
-        
-        let section = indexPaths.last?.section ?? 0
-        let row = indexPaths.last?.row ?? 0
-        
-        let lastSection = self.sectionDate.count - 1
-        let lastRow = getTableActivitiesFromSection(section).count - 1
-        
-        if section == lastSection && row > lastRow - 1 {
-            let results = getTableActivitiesFromSection(section)
-            let activity = results[lastRow]
-            
-            loadActivity(idActivity: activity.idActivity)
-        }
+    func numberOfSections(in tableView: UITableView) -> Int {
+        return sectionDate.count
     }
     
-    func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) {
-        //print("cancelPrefetchingForRowsAt \(indexPaths)")
+    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return getTableActivitiesFromSection(section).count
     }
     
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
@@ -184,13 +168,13 @@ class NCActivity: UIViewController, UITableViewDataSource, UITableViewDelegate,
             let results = getTableActivitiesFromSection(indexPath.section)
             let activity = results[indexPath.row]
             var orderKeysId = [String]()
-
+            
             cell.idActivity = activity.idActivity
             cell.account = activity.account
             cell.avatar.image = nil
             cell.avatar.isHidden = true
             cell.subjectTrailingConstraint.constant = 10
-
+            
             // icon
             if activity.icon.count > 0 {
                 
@@ -220,7 +204,7 @@ class NCActivity: UIViewController, UITableViewDataSource, UITableViewDelegate,
                     }
                 }
             }
-    
+            
             // avatar
             if activity.user.count > 0 && activity.user != appDelegate.activeUserID {
                 
@@ -289,164 +273,45 @@ class NCActivity: UIViewController, UITableViewDataSource, UITableViewDelegate,
                 cell.collectionViewHeightConstraint.constant = 60
             }
             cell.collectionView.reloadData()
-
+            
             return cell
         }
         
         return UITableViewCell()
     }
-    
-    // MARK: NC API
-    
-    @objc func loadActivityRefreshing() {
-        loadActivity(idActivity: 0)
-    }
+}
 
-    @objc func loadActivity(idActivity: Int) {
+extension NCActivity: UITableViewDataSourcePrefetching {
+    
+    func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
         
-        if loadingActivity {
-            return
-        } else {
-            loadingActivity = true
-        }
+        let section = indexPaths.last?.section ?? 0
+        let row = indexPaths.last?.row ?? 0
         
-        if idActivity > 0 {
-            NCUtility.sharedInstance.startActivityIndicator(view: self.view, bottom: 50)
-        }
+        let lastSection = self.sectionDate.count - 1
+        let lastRow = getTableActivitiesFromSection(section).count - 1
         
-        OCNetworking.sharedManager().getActivityWithAccount(appDelegate.activeAccount, since: idActivity, limit: 100, link: "", completion: { (account, listOfActivity, message, errorCode) in
-            
-            if errorCode == 0 && account == self.appDelegate.activeAccount {
-                NCManageDatabase.sharedInstance.addActivity(listOfActivity as! [OCActivity], account: account!)
-                
-                self.loadDataSource()
-            }
-            
-            self.refreshControl.endRefreshing()
-            NCUtility.sharedInstance.stopActivityIndicator()
+        if section == lastSection && row > lastRow - 1 {
+            let results = getTableActivitiesFromSection(section)
+            let activity = results[lastRow]
             
-            self.loadingActivity = false
-        })
-    }
-}
-
-class activityTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
-    
-    private let appDelegate = UIApplication.shared.delegate as! AppDelegate
-
-    @IBOutlet weak var collectionView: UICollectionView!
-    
-    @IBOutlet weak var icon: UIImageView!
-    @IBOutlet weak var avatar: UIImageView!
-    @IBOutlet weak var subject: UILabel!
-    @IBOutlet weak var subjectTrailingConstraint: NSLayoutConstraint!
-    @IBOutlet weak var collectionViewHeightConstraint: NSLayoutConstraint!
-
-    var idActivity: Int = 0
-    var account: String = ""
-    var activityPreviews = [tableActivityPreview]()
-    
-    override func awakeFromNib() {
-        super.awakeFromNib()
-        
-        collectionView.delegate = self
-        collectionView.dataSource = self
-    }
-    
-    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
-        return CGSize(width: 50, height: 50)
-    }
-    
-    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
-        return 20
-    }
-    
-    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
-        return UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
-    }
-    
-    func numberOfSections(in collectionView: UICollectionView) -> Int {
-        return 1
+            loadActivity(idActivity: activity.idActivity)
+        }
     }
     
-    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
-        return activityPreviews.count
+    func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) {
+        //print("cancelPrefetchingForRowsAt \(indexPaths)")
     }
-    
-    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
-      
-        if let cell: activityCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as? activityCollectionViewCell {
-            
-            cell.imageView.image = nil
-            
-            let activityPreview = activityPreviews[indexPath.row]
-            let fileID = String(activityPreview.fileId)
+}
 
-            // Trashbin
-            if activityPreview.view == "trashbin" {
-                
-                let source = activityPreview.source
-                
-                DispatchQueue.global().async {
-                    if let imageNamePath = NCUtility.sharedInstance.convertSVGtoPNGWriteToUserData(svgUrlString: source, fileName: nil, width: 100, rewrite: false) {
-                        DispatchQueue.main.async {
-                            if let image = UIImage(contentsOfFile: imageNamePath) {
-                                cell.imageView.image = image
-                            }
-                        }
-                    }
-                }
-                
-            } else {
-                
-                if activityPreview.isMimeTypeIcon {
-                    
-                    let source = activityPreview.source
+// MARK: - Collection View
 
-                    DispatchQueue.global().async {
-                        if let imageNamePath = NCUtility.sharedInstance.convertSVGtoPNGWriteToUserData(svgUrlString: source, fileName: nil, width: 100, rewrite: false) {
-                            DispatchQueue.main.async {
-                                if let image = UIImage(contentsOfFile: imageNamePath) {
-                                    cell.imageView.image = image
-                                }
-                            }
-                        }
-                    }
-                    
-                } else {
-                    
-                    if let activitySubjectRich = NCManageDatabase.sharedInstance.getActivitySubjectRich(account: account, idActivity: idActivity, id: fileID) {
-                    
-                        let fileNamePath = CCUtility.getDirectoryUserData() + "/" + activitySubjectRich.name
-                        
-                        if FileManager.default.fileExists(atPath: fileNamePath) {
-                            
-                            if let image = UIImage(contentsOfFile: fileNamePath) {
-                                cell.imageView.image = image
-                            }
-                            
-                        } else {
-                            
-                            OCNetworking.sharedManager()?.downloadPreview(withAccount: appDelegate.activeAccount, serverPath: activityPreview.source, fileNamePath: fileNamePath, completion: { (account, image, message, errorCode) in
-                                if errorCode == 0 {
-                                    cell.imageView.image = image
-                                }
-                            })
-                        }
-                    }
-                }
-            }
-            
-            return cell
-        }
-        
-        return UICollectionViewCell()
-    }
+extension activityTableViewCell: UICollectionViewDelegate {
     
     func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
         
         let activityPreview = activityPreviews[indexPath.row]
-
+        
         if activityPreview.view == "trashbin" {
             
             var responder: UIResponder? = collectionView
@@ -457,10 +322,12 @@ class activityTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollec
                 }
             }
             if (responder as? UIViewController)!.navigationController != nil {
-                
                 if let viewController = UIStoryboard.init(name: "NCTrash", bundle: nil).instantiateInitialViewController() as? NCTrash {
-                    viewController.scrollToFileID = String(activityPreview.fileId)
-                    (responder as? UIViewController)!.navigationController?.pushViewController(viewController, animated: true)
+                    if let result = NCManageDatabase.sharedInstance.getTrashItem(fileID: String(activityPreview.fileId), account: activityPreview.account) {
+                        viewController.scrollToFileID = result.fileID
+                        viewController.path = result.filePath
+                        (responder as? UIViewController)!.navigationController?.pushViewController(viewController, animated: true)
+                    }
                 }
             }
             
@@ -507,7 +374,7 @@ class activityTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollec
                     OCNetworking.sharedManager()?.readFile(withAccount: activityPreview.account, serverUrl: serverUrl, fileName: fileName, completion: { (account, metadata, message, errorCode) in
                         
                         NCUtility.sharedInstance.stopActivityIndicator()
-
+                        
                         if account == self.appDelegate.activeAccount && errorCode == 0 {
                             
                             // move from id to oc:id + instanceid (fileID)
@@ -532,6 +399,84 @@ class activityTableViewCell: UITableViewCell, UICollectionViewDelegate, UICollec
     }
 }
 
+extension activityTableViewCell: UICollectionViewDataSource {
+    
+    func numberOfSections(in collectionView: UICollectionView) -> Int {
+        return 1
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return activityPreviews.count
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        
+        if let cell: activityCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as? activityCollectionViewCell {
+            
+            cell.imageView.image = nil
+            
+            let activityPreview = activityPreviews[indexPath.row]
+            let fileID = String(activityPreview.fileId)
+            
+            // Trashbin
+            if activityPreview.view == "trashbin" {
+                
+                let source = activityPreview.source
+                
+                NCUtility.sharedInstance.convertSVGtoPNGWriteToUserData(svgUrlString: source, fileName: nil, width: 100, rewrite: false) { (imageNamePath) in
+                    if imageNamePath != nil {
+                        if let image = UIImage(contentsOfFile: imageNamePath!) {
+                            cell.imageView.image = image
+                        }
+                    }
+                }
+                
+            } else {
+                
+                if activityPreview.isMimeTypeIcon {
+                    
+                    let source = activityPreview.source
+                    
+                    NCUtility.sharedInstance.convertSVGtoPNGWriteToUserData(svgUrlString: source, fileName: nil, width: 100, rewrite: false) { (imageNamePath) in
+                        if imageNamePath != nil {
+                            if let image = UIImage(contentsOfFile: imageNamePath!) {
+                                cell.imageView.image = image
+                            }
+                        }
+                    }
+                    
+                } else {
+                    
+                    if let activitySubjectRich = NCManageDatabase.sharedInstance.getActivitySubjectRich(account: account, idActivity: idActivity, id: fileID) {
+                        
+                        let fileNamePath = CCUtility.getDirectoryUserData() + "/" + activitySubjectRich.name
+                        
+                        if FileManager.default.fileExists(atPath: fileNamePath) {
+                            
+                            if let image = UIImage(contentsOfFile: fileNamePath) {
+                                cell.imageView.image = image
+                            }
+                            
+                        } else {
+                            
+                            OCNetworking.sharedManager()?.downloadPreview(withAccount: appDelegate.activeAccount, serverPath: activityPreview.source, fileNamePath: fileNamePath, completion: { (account, image, message, errorCode) in
+                                if errorCode == 0 {
+                                    cell.imageView.image = image
+                                }
+                            })
+                        }
+                    }
+                }
+            }
+            
+            return cell
+        }
+        
+        return UICollectionViewCell()
+    }
+    
+}
+
 class activityCollectionViewCell: UICollectionViewCell {
     
     @IBOutlet weak var imageView: UIImageView!
@@ -540,3 +485,80 @@ class activityCollectionViewCell: UICollectionViewCell {
         super.awakeFromNib()
     }
 }
+
+extension activityTableViewCell: UICollectionViewDelegateFlowLayout {
+    
+    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
+        return CGSize(width: 50, height: 50)
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
+        return 20
+    }
+    
+    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
+        return UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
+    }
+}
+
+// MARK: - NC API & Algorithm
+
+extension NCActivity {
+    
+    func loadDataSource() {
+        
+        sectionDate.removeAll()
+        
+        activities = NCManageDatabase.sharedInstance.getActivity(predicate: NSPredicate(format: "account == %@", appDelegate.activeAccount))
+        for tableActivity in activities {
+            guard let date = Calendar.current.date(from: Calendar.current.dateComponents([.year, .month, .day], from: tableActivity.date as Date)) else {
+                continue
+            }
+            if !sectionDate.contains(date) {
+                sectionDate.append(date)
+            }
+        }
+        tableView.reloadData()
+    }
+    
+    func getTableActivitiesFromSection(_ section: Int) -> [tableActivity] {
+        let startDate = sectionDate[section]
+        let endDate: Date = {
+            let components = DateComponents(day: 1, second: -1)
+            return Calendar.current.date(byAdding: components, to: startDate)!
+        }()
+        
+        return NCManageDatabase.sharedInstance.getActivity(predicate: NSPredicate(format: "account == %@ && date BETWEEN %@", appDelegate.activeAccount, [startDate, endDate]))
+    }
+    
+    @objc func loadActivityRefreshing() {
+        loadActivity(idActivity: 0)
+    }
+    
+    @objc func loadActivity(idActivity: Int) {
+        
+        if loadingActivity {
+            return
+        } else {
+            loadingActivity = true
+        }
+        
+        if idActivity > 0 {
+            NCUtility.sharedInstance.startActivityIndicator(view: self.view, bottom: 50)
+        }
+        
+        OCNetworking.sharedManager().getActivityWithAccount(appDelegate.activeAccount, since: idActivity, limit: 100, link: "", completion: { (account, listOfActivity, message, errorCode) in
+            
+            if errorCode == 0 && account == self.appDelegate.activeAccount {
+                NCManageDatabase.sharedInstance.addActivity(listOfActivity as! [OCActivity], account: account!)
+                
+                self.loadDataSource()
+            }
+            
+            self.refreshControl.endRefreshing()
+            NCUtility.sharedInstance.stopActivityIndicator()
+            
+            self.loadingActivity = false
+        })
+    }
+}

+ 1 - 0
iOSClient/AppDelegate.h

@@ -169,6 +169,7 @@
 
 // Task Networking
 - (void)loadAutoDownloadUpload;
+- (void)startLoadAutoDownloadUpload;
 
 // Maintenance Mode
 - (void)maintenanceMode:(BOOL)mode;

+ 15 - 3
iOSClient/AppDelegate.m

@@ -90,6 +90,11 @@
     if (![[NSFileManager defaultManager] fileExistsAtPath:path])
         [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
     
+    // Directory Excluded From Backup
+    [CCUtility addSkipBackupAttributeToItemAtURL:[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]];
+    [CCUtility addSkipBackupAttributeToItemAtURL:[[CCUtility getDirectoryGroup] URLByAppendingPathComponent:k_DirectoryProviderStorage]];
+    [CCUtility addSkipBackupAttributeToItemAtURL:[[CCUtility getDirectoryGroup] URLByAppendingPathComponent:k_appUserData]];
+    
     // Verify upgrade
     if ([self upgrade]) {
     
@@ -518,8 +523,8 @@
 - (void)configDynamicShortcutItems
 {
     NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;
-
-    UIApplicationShortcutIcon *shortcutMediaIcon = [UIApplicationShortcutIcon iconWithTemplateImageName:@"quickActionMedia"];
+    
+    UIApplicationShortcutIcon *shortcutMediaIcon = [UIApplicationShortcutIcon iconWithTemplateImageName:@"media"];
     UIApplicationShortcutItem *shortcutMedia = [[UIApplicationShortcutItem alloc] initWithType:[NSString stringWithFormat:@"%@.media", bundleId] localizedTitle:NSLocalizedString(@"_media_", nil) localizedSubtitle:nil icon:shortcutMediaIcon userInfo:nil];
    
     // add the array to our app
@@ -1170,7 +1175,7 @@
     
     // Detect E2EE
     NSString *saveserverUrl = @"";
-    NSArray *metadatasForE2EE = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"status != %d", k_metadataStatusNormal] sorted:nil ascending:NO];
+    NSArray *metadatasForE2EE = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"status != %d", k_metadataStatusNormal] sorted:@"serverUrl" ascending:NO];
     for (tableMetadata *metadata in metadatasForE2EE) {
         if (![saveserverUrl isEqualToString:metadata.serverUrl]) {
             saveserverUrl = metadata.serverUrl;
@@ -1402,6 +1407,13 @@
     _timerProcessAutoDownloadUpload = [NSTimer scheduledTimerWithTimeInterval:k_timerProcessAutoDownloadUpload target:self selector:@selector(loadAutoDownloadUpload) userInfo:nil repeats:YES];
 }
 
+- (void)startLoadAutoDownloadUpload
+{
+    if (self.timerProcessAutoDownloadUpload.isValid) {
+        [self performSelectorOnMainThread:@selector(loadAutoDownloadUpload) withObject:nil waitUntilDone:YES];
+    }
+}
+
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ===== Open CCUploadFromOtherUpp  =====
 #pragma --------------------------------------------------------------------------------------------

+ 118 - 0
iOSClient/AudioRecorder/NCAudioRecorderViewController.storyboard

@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="9IE-bj-VJb">
+    <device id="retina4_7" orientation="portrait">
+        <adaptation id="fullscreen"/>
+    </device>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <scenes>
+        <!--Audio Recorder View Controller-->
+        <scene sceneID="eNh-2I-c1P">
+            <objects>
+                <viewController storyboardIdentifier="RecorderViewController" modalPresentationStyle="currentContext" id="9IE-bj-VJb" customClass="NCAudioRecorderViewController" customModule="Nextcloud" customModuleProvider="target" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="fma-yb-dlL"/>
+                        <viewControllerLayoutGuide type="bottom" id="6hQ-x4-s9V"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="tQN-Gk-6M1">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tRu-33-Q2b" userLabel="buttonView">
+                                <rect key="frame" x="0.0" y="20" width="375" height="647"/>
+                                <connections>
+                                    <action selector="touchViewController" destination="9IE-bj-VJb" eventType="touchUpInside" id="Dex-dc-29L"/>
+                                </connections>
+                            </button>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Ztv-M0-yUI" userLabel="contentContainerView">
+                                <rect key="frame" x="87.5" y="208.5" width="200" height="250"/>
+                                <subviews>
+                                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vr6-IX-Yee" customClass="VoiceRecordHUD" customModule="Nextcloud" customModuleProvider="target">
+                                        <rect key="frame" x="2" y="27" width="196" height="196"/>
+                                        <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <constraints>
+                                            <constraint firstAttribute="width" secondItem="vr6-IX-Yee" secondAttribute="height" id="c7R-AE-rou"/>
+                                        </constraints>
+                                        <userDefinedRuntimeAttributes>
+                                            <userDefinedRuntimeAttribute type="number" keyPath="rate">
+                                                <real key="value" value="0.5"/>
+                                            </userDefinedRuntimeAttribute>
+                                            <userDefinedRuntimeAttribute type="color" keyPath="fillColor">
+                                                <color key="value" red="0.0" green="1" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                            </userDefinedRuntimeAttribute>
+                                        </userDefinedRuntimeAttributes>
+                                    </view>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="120″" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="yIp-rq-klm">
+                                        <rect key="frame" x="85" y="10" width="30" height="17"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="bottom" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Lnv-LR-qq5" userLabel="button">
+                                        <rect key="frame" x="0.0" y="0.0" width="200" height="250"/>
+                                        <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
+                                        <state key="normal">
+                                            <color key="titleColor" red="0.94117647059999998" green="0.91764705879999997" blue="0.85490196080000003" alpha="1" colorSpace="calibratedRGB"/>
+                                        </state>
+                                        <connections>
+                                            <action selector="startStop" destination="9IE-bj-VJb" eventType="touchUpInside" id="B8V-Tg-Hbf"/>
+                                        </connections>
+                                    </button>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="tap to start" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3Wm-qO-FzJ" userLabel="start stop">
+                                        <rect key="frame" x="64" y="225" width="72" height="17"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                        <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                <constraints>
+                                    <constraint firstItem="yIp-rq-klm" firstAttribute="top" secondItem="Ztv-M0-yUI" secondAttribute="top" constant="10" id="1S8-2v-d7k"/>
+                                    <constraint firstItem="3Wm-qO-FzJ" firstAttribute="centerX" secondItem="Lnv-LR-qq5" secondAttribute="centerX" id="2UV-Gt-2oO"/>
+                                    <constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="vr6-IX-Yee" secondAttribute="trailing" id="6e6-C9-ZWQ"/>
+                                    <constraint firstItem="yIp-rq-klm" firstAttribute="bottom" secondItem="vr6-IX-Yee" secondAttribute="top" id="E3m-Yu-zdJ"/>
+                                    <constraint firstAttribute="height" constant="250" id="G5W-ie-MCH"/>
+                                    <constraint firstItem="Lnv-LR-qq5" firstAttribute="leading" secondItem="Ztv-M0-yUI" secondAttribute="leading" id="JlM-Ww-iut"/>
+                                    <constraint firstAttribute="bottom" secondItem="Lnv-LR-qq5" secondAttribute="bottom" id="Kzr-BQ-zK4"/>
+                                    <constraint firstAttribute="trailing" secondItem="Lnv-LR-qq5" secondAttribute="trailing" id="NNn-Ce-Y8V"/>
+                                    <constraint firstAttribute="width" constant="200" id="Qu2-eD-5VF"/>
+                                    <constraint firstItem="vr6-IX-Yee" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Ztv-M0-yUI" secondAttribute="leading" id="Wmx-H6-3OK"/>
+                                    <constraint firstAttribute="centerX" secondItem="vr6-IX-Yee" secondAttribute="centerX" id="Zvz-EB-nL6"/>
+                                    <constraint firstItem="3Wm-qO-FzJ" firstAttribute="top" secondItem="Lnv-LR-qq5" secondAttribute="bottom" constant="-25" id="a8Q-Z1-NFp"/>
+                                    <constraint firstAttribute="centerX" secondItem="yIp-rq-klm" secondAttribute="centerX" id="hwa-S6-oPz"/>
+                                    <constraint firstAttribute="centerY" secondItem="vr6-IX-Yee" secondAttribute="centerY" id="iqe-Ov-fVD"/>
+                                    <constraint firstItem="Lnv-LR-qq5" firstAttribute="top" secondItem="Ztv-M0-yUI" secondAttribute="top" id="mrG-va-2Su"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
+                                        <integer key="value" value="10"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
+                        <constraints>
+                            <constraint firstItem="Ztv-M0-yUI" firstAttribute="centerY" secondItem="tQN-Gk-6M1" secondAttribute="centerY" id="4ah-zH-qPv"/>
+                            <constraint firstItem="6hQ-x4-s9V" firstAttribute="top" secondItem="tRu-33-Q2b" secondAttribute="bottom" id="Iyw-Xf-NUq"/>
+                            <constraint firstItem="Ztv-M0-yUI" firstAttribute="centerX" secondItem="tQN-Gk-6M1" secondAttribute="centerX" id="QMu-hw-0s3"/>
+                            <constraint firstItem="tRu-33-Q2b" firstAttribute="leading" secondItem="tQN-Gk-6M1" secondAttribute="leading" id="iDG-p5-AZP"/>
+                            <constraint firstItem="tRu-33-Q2b" firstAttribute="top" secondItem="fma-yb-dlL" secondAttribute="bottom" id="rco-z5-Lgs"/>
+                            <constraint firstAttribute="trailing" secondItem="tRu-33-Q2b" secondAttribute="trailing" id="uMJ-XD-sjl"/>
+                        </constraints>
+                    </view>
+                    <connections>
+                        <outlet property="contentContainerView" destination="Ztv-M0-yUI" id="P6f-ew-Dyb"/>
+                        <outlet property="durationLabel" destination="yIp-rq-klm" id="a8F-JI-uNe"/>
+                        <outlet property="startStopLabel" destination="3Wm-qO-FzJ" id="2oa-5C-G2K"/>
+                        <outlet property="voiceRecordHUD" destination="vr6-IX-Yee" id="s4E-Ka-QV9"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="Nq7-s5-9VP" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="599" y="140"/>
+        </scene>
+    </scenes>
+</document>

+ 307 - 0
iOSClient/AudioRecorder/NCAudioRecorderViewController.swift

@@ -0,0 +1,307 @@
+//
+//  NCAudioRecorderViewController.swift
+//  Nextcloud
+//
+//  Created by Marino Faggiana on 08/03/19.
+//  Copyright (c) 2017 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/>.
+//
+//  --------------------------------
+//  Based on code of Venkat Kukunuru
+//  --------------------------------
+
+import Foundation
+import UIKit
+import AVFoundation
+import QuartzCore
+
+@objc protocol NCAudioRecorderViewControllerDelegate : class {
+    func didFinishRecording(_ viewController: NCAudioRecorderViewController, fileName: String)
+}
+
+class NCAudioRecorderViewController: UIViewController , NCAudioRecorderDelegate {
+    
+    open weak var delegate: NCAudioRecorderViewControllerDelegate?
+    var recording: NCAudioRecorder!
+    var recordDuration: TimeInterval = 0
+    var fileName: String = ""
+    
+    @IBOutlet weak var contentContainerView: UIView!
+    @IBOutlet weak var durationLabel: UILabel!
+    @IBOutlet weak var startStopLabel: UILabel!
+    @IBOutlet weak var voiceRecordHUD: VoiceRecordHUD!
+    
+    // MARK: View Life Cycle
+    
+    override func viewDidLoad() {
+        super.viewDidLoad()
+    }
+    
+    override func viewWillAppear(_ animated: Bool) {
+        super.viewWillAppear(animated)
+        
+        contentContainerView.backgroundColor = NCBrandColor.sharedInstance.brand
+        voiceRecordHUD.update(0.0)
+        voiceRecordHUD.fillColor = UIColor.green
+        durationLabel.text = ""
+        startStopLabel.text = NSLocalizedString("_voice_memo_start_", comment: "")
+    }
+    
+    func createRecorder(fileName: String) {
+        
+        self.fileName = fileName
+        recording = NCAudioRecorder(to: fileName)
+        recording.delegate = self
+
+        DispatchQueue.global().async {
+            // Background thread
+            do {
+                try self.recording.prepare()
+            } catch {
+                print(error)
+            }
+        }
+    }
+    
+    @IBAction func touchViewController() {
+        
+        if recording.state == .record {
+            startStop()
+        } else {
+            dismiss(animated: true, completion: nil)
+        }
+    }
+    
+    @IBAction func startStop() {
+        
+        if recording.state == .record {
+        
+            recordDuration = 0
+            recording.stop()
+            voiceRecordHUD.update(0.0)
+        
+            dismiss(animated: true) {
+                self.delegate?.didFinishRecording(self, fileName: self.fileName)
+            }
+        } else {
+            
+            recordDuration = 0
+            do {
+                try recording.record()
+                startStopLabel.text = NSLocalizedString("_voice_memo_stop_", comment: "")
+            } catch {
+                print(error)
+            }
+        }
+    }
+    
+    func audioMeterDidUpdate(_ db: Float) {
+        
+        //print("db level: %f", db)
+        
+        self.recording.recorder?.updateMeters()
+        let ALPHA = 0.05
+        let peakPower = pow(10, (ALPHA * Double((self.recording.recorder?.peakPower(forChannel: 0))!)))
+        var rate: Double = 0.0
+        if (peakPower <= 0.2) {
+            rate = 0.2
+        } else if (peakPower > 0.9) {
+            rate = 1.0
+        } else {
+            rate = peakPower
+        }
+        
+        voiceRecordHUD.update(CGFloat(rate))
+        voiceRecordHUD.fillColor = UIColor.green
+        recordDuration += 1
+        durationLabel.text = NCUtility.sharedInstance.formatSecondsToString(recordDuration/60)
+    }
+}
+
+@objc public protocol NCAudioRecorderDelegate: AVAudioRecorderDelegate {
+    @objc optional func audioMeterDidUpdate(_ dB: Float)
+}
+
+open class NCAudioRecorder : NSObject {
+    
+    @objc public enum State: Int {
+        case none, record, play
+    }
+    
+    static var directory: String {
+        return NSTemporaryDirectory()
+    }
+    
+    open weak var delegate: NCAudioRecorderDelegate?
+    open fileprivate(set) var url: URL
+    open fileprivate(set) var state: State = .none
+    
+    open var bitRate = 192000
+    open var sampleRate = 44100.0
+    open var channels = 1
+    
+    fileprivate let session = AVAudioSession.sharedInstance()
+    var recorder: AVAudioRecorder?
+    fileprivate var player: AVAudioPlayer?
+    fileprivate var link: CADisplayLink?
+    
+    var metering: Bool {
+        return delegate?.responds(to: #selector(NCAudioRecorderDelegate.audioMeterDidUpdate(_:))) == true
+    }
+    
+    // MARK: - Initializers
+    
+    public init(to: String) {
+        url = URL(fileURLWithPath: NCAudioRecorder.directory).appendingPathComponent(to)
+        super.init()
+    }
+    
+    // MARK: - Record
+    
+    open func prepare() throws {
+        let settings: [String: AnyObject] = [
+            AVFormatIDKey : NSNumber(value: Int32(kAudioFormatAppleLossless) as Int32),
+            AVEncoderAudioQualityKey: AVAudioQuality.max.rawValue as AnyObject,
+            AVEncoderBitRateKey: bitRate as AnyObject,
+            AVNumberOfChannelsKey: channels as AnyObject,
+            AVSampleRateKey: sampleRate as AnyObject
+        ]
+        
+        recorder = try AVAudioRecorder(url: url, settings: settings)
+        recorder?.prepareToRecord()
+        recorder?.delegate = delegate
+        recorder?.isMeteringEnabled = metering
+    }
+    
+    open func record() throws {
+        if recorder == nil {
+            try prepare()
+        }
+        
+        try session.setCategory(.playAndRecord, mode: .default)
+        try session.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)
+        
+        recorder?.record()
+        state = .record
+        
+        if metering {
+            startMetering()
+        }
+    }
+    
+    open func play() throws {
+        if recorder == nil {
+            try prepare()
+        }
+        
+        try session.setCategory(.playback, mode: .default)
+        try AVAudioSession.sharedInstance().setActive(true)
+
+        player = try AVAudioPlayer(contentsOf: url)
+        player?.prepareToPlay()
+
+        player?.play()
+        state = .play
+    }
+    
+    open func stop() {
+        switch state {
+        case .play:
+            player?.stop()
+            player = nil
+        case .record:
+            recorder?.stop()
+            recorder = nil
+            stopMetering()
+        default:
+            break
+        }
+        
+        state = .none
+    }
+    
+    // MARK: - Metering
+    
+    @objc func updateMeter() {
+        guard let recorder = recorder else { return }
+        
+        recorder.updateMeters()
+        
+        let dB = recorder.averagePower(forChannel: 0)
+        
+        delegate?.audioMeterDidUpdate?(dB)
+    }
+    
+    fileprivate func startMetering() {
+        link = CADisplayLink(target: self, selector: #selector(NCAudioRecorder.updateMeter))
+        link?.add(to: RunLoop.current, forMode: RunLoop.Mode.common)
+    }
+    
+    fileprivate func stopMetering() {
+        link?.invalidate()
+        link = nil
+    }
+}
+
+@IBDesignable
+class VoiceRecordHUD: UIView {
+    @IBInspectable var rate: CGFloat = 0.0
+    
+    @IBInspectable var fillColor: UIColor = UIColor.green {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    var image: UIImage! {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        image = UIImage(named: "microphone")
+    }
+    
+    required init?(coder aDecoder: NSCoder) {
+        super.init(coder: aDecoder)
+        image = UIImage(named: "microphone")
+    }
+    
+    func update(_ rate: CGFloat) {
+        self.rate = rate
+        setNeedsDisplay()
+    }
+    
+    override func draw(_ rect: CGRect) {
+        let context = UIGraphicsGetCurrentContext()
+        context?.translateBy(x: 0, y: bounds.size.height)
+        context?.scaleBy(x: 1, y: -1)
+        
+        context?.draw(image.cgImage!, in: bounds)
+        context?.clip(to: bounds, mask: image.cgImage!)
+        
+        context?.setFillColor(fillColor.cgColor.components!)
+        context?.fill(CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height * rate))
+    }
+    
+    override func prepareForInterfaceBuilder() {
+        let bundle = Bundle(for: type(of: self))
+        image = UIImage(named: "microphone", in: bundle, compatibleWith: self.traitCollection)
+    }
+}

+ 1 - 1
iOSClient/Brand/File_Provider_Extension.plist

@@ -17,7 +17,7 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.23.1</string>
+	<string>2.23.2</string>
 	<key>CFBundleVersion</key>
 	<string>10</string>
 	<key>NSExtension</key>

+ 2 - 3
iOSClient/Brand/NCBrand.swift

@@ -90,9 +90,8 @@ class NCBrandColor: NSObject {
     // Capabilities Group
     @objc public let capabilitiesGroups:                String = "group.it.twsweb.Crypto-Cloud"
     
-    // Database key encryption key 64byte AES-256+SHA2
-    @objc public var databaseEncryptionKey:             String = "LdFNb00N+ywBuNGJRjCUuDt1zIXK/PX82ZNHWochfu1is8TorIERQi1aJsAMLC3rK2BB0uMjh2kNZ9Dcwx/G5Q=="
-
+    // Database key 64 char ASCII (for encryption AES-256+SHA2)
+    @objc public var databaseEncryptionKey:             String = "1234567890123456789012345678901234567890123456789012345678901234"
     
     // Options
     @objc public let use_login_web_personalized:        Bool = false                                                // Don't touch me !!

+ 1 - 1
iOSClient/Brand/Notification_Service_Extension.plist

@@ -17,7 +17,7 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.23.1</string>
+	<string>2.23.2</string>
 	<key>CFBundleVersion</key>
 	<string>10</string>
 	<key>NSExtension</key>

+ 1 - 1
iOSClient/Brand/Share.plist

@@ -17,7 +17,7 @@
 	<key>CFBundlePackageType</key>
 	<string>XPC!</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.23.1</string>
+	<string>2.23.2</string>
 	<key>CFBundleVersion</key>
 	<string>10</string>
 	<key>NSAppTransportSecurity</key>

+ 1 - 1
iOSClient/Brand/iOSClient.plist

@@ -46,7 +46,7 @@
 	<key>CFBundlePackageType</key>
 	<string>APPL</string>
 	<key>CFBundleShortVersionString</key>
-	<string>2.23.1</string>
+	<string>2.23.2</string>
 	<key>CFBundleSignature</key>
 	<string>????</string>
 	<key>CFBundleVersion</key>

+ 24 - 0
iOSClient/Database/NCDatabase.swift

@@ -142,6 +142,30 @@ class tableCapabilities: Object {
     @objc dynamic var endToEndEncryptionVersion = ""
     let richdocumentsMimetypes = List<String>()
     @objc dynamic var richdocumentsDirectEditing: Bool = false
+    // FILES SHARING
+    @objc dynamic var isFilesSharingAPIEnabled: Bool = false
+    @objc dynamic var filesSharingDefaulPermissions: Int = 0
+    @objc dynamic var isFilesSharingGroupSharing: Bool = false
+    @objc dynamic var isFilesSharingReSharing: Bool = false
+    @objc dynamic var isFilesSharingPublicShareLinkEnabled: Bool = false
+    @objc dynamic var isFilesSharingAllowPublicUploadsEnabled: Bool = false
+    @objc dynamic var isFilesSharingAllowPublicUserSendMail: Bool = false
+    @objc dynamic var isFilesSharingAllowPublicUploadFilesDrop: Bool = false
+    @objc dynamic var isFilesSharingAllowPublicMultipleLinks: Bool = false
+    @objc dynamic var isFilesSharingPublicExpireDateByDefaultEnabled: Bool = false
+    @objc dynamic var isFilesSharingPublicExpireDateEnforceEnabled: Bool = false
+    @objc dynamic var filesSharingPublicExpireDateDays : Int = 0
+    @objc dynamic var isFilesSharingPublicPasswordEnforced: Bool = false
+    @objc dynamic var isFilesSharingAllowUserSendMail: Bool = false
+    @objc dynamic var isFilesSharingUserExpireDate: Bool = false
+    @objc dynamic var isFilesSharingGroupEnabled: Bool = false
+    @objc dynamic var isFilesSharingGroupExpireDate: Bool = false
+    @objc dynamic var isFilesSharingFederationAllowUserSendShares: Bool = false
+    @objc dynamic var isFilesSharingFederationAllowUserReceiveShares: Bool = false
+    @objc dynamic var isFilesSharingFederationExpireDate: Bool = false
+    @objc dynamic var isFileSharingShareByMailEnabled: Bool = false
+    @objc dynamic var isFileSharingShareByMailPassword: Bool = false
+    @objc dynamic var isFileSharingShareByMailUploadFilesDrop: Bool = false
 }
 
 class tableCertificates: Object {

+ 69 - 32
iOSClient/Database/NCManageDatabase.swift

@@ -49,7 +49,7 @@ class NCManageDatabase: NSObject {
         
         // Encrypting the database file on disk with AES-256+SHA2 by supplying a 64-byte encryption key
         if NCBrandOptions.sharedInstance.use_database_encryption {
-            if let keyData = Data(base64Encoded: NCBrandOptions.sharedInstance.databaseEncryptionKey) {
+            if let keyData = NCBrandOptions.sharedInstance.databaseEncryptionKey.data(using: String.Encoding.utf8, allowLossyConversion: false) {
                 configCompact.encryptionKey = keyData
             }
         }
@@ -64,7 +64,7 @@ class NCManageDatabase: NSObject {
         var config = Realm.Configuration(
         
             fileURL: dirGroup?.appendingPathComponent("\(k_appDatabaseNextcloud)/\(k_databaseDefault)"),
-            schemaVersion: 42,
+            schemaVersion: 43,
             
             // 10 : Version 2.18.0
             // 11 : Version 2.18.2
@@ -99,7 +99,7 @@ class NCManageDatabase: NSObject {
             // 40 : Version 2.22.9.3
             // 41 : Version 2.22.9.5
             // 42 : Version 2.23.1.0
-            
+            // 43 : Version 2.23.2.0
 
             migrationBlock: { migration, oldSchemaVersion in
                 // We haven’t migrated anything yet, so oldSchemaVersion == 0
@@ -131,7 +131,7 @@ class NCManageDatabase: NSObject {
         
         // Encrypting the database file on disk with AES-256+SHA2 by supplying a 64-byte encryption key
         if NCBrandOptions.sharedInstance.use_database_encryption {
-            if let keyData = Data(base64Encoded: NCBrandOptions.sharedInstance.databaseEncryptionKey) {
+            if let keyData = NCBrandOptions.sharedInstance.databaseEncryptionKey.data(using: String.Encoding.utf8, allowLossyConversion: false) {
                 config.encryptionKey = keyData
             }
         }
@@ -766,10 +766,36 @@ class NCManageDatabase: NSObject {
                     resultCapabilities.richdocumentsMimetypes.append(mimeType as! String)
                 }
                 resultCapabilities.richdocumentsDirectEditing = capabilities.richdocumentsDirectEditing
+                // FILES SHARING
+                resultCapabilities.isFilesSharingAPIEnabled = capabilities.isFilesSharingAPIEnabled
+                resultCapabilities.filesSharingDefaulPermissions = capabilities.filesSharingDefaulPermissions
+                resultCapabilities.isFilesSharingGroupSharing = capabilities.isFilesSharingGroupSharing
+                resultCapabilities.isFilesSharingReSharing = capabilities.isFilesSharingReSharing
+                resultCapabilities.isFilesSharingPublicShareLinkEnabled = capabilities.isFilesSharingPublicShareLinkEnabled
+                resultCapabilities.isFilesSharingAllowPublicUploadsEnabled = capabilities.isFilesSharingAllowPublicUploadsEnabled
+                resultCapabilities.isFilesSharingAllowPublicUserSendMail = capabilities.isFilesSharingAllowPublicUserSendMail
+                resultCapabilities.isFilesSharingAllowPublicUploadFilesDrop = capabilities.isFilesSharingAllowPublicUploadFilesDrop
+                resultCapabilities.isFilesSharingAllowPublicMultipleLinks = capabilities.isFilesSharingAllowPublicMultipleLinks
+                resultCapabilities.isFilesSharingPublicExpireDateByDefaultEnabled = capabilities.isFilesSharingPublicExpireDateByDefaultEnabled
+                resultCapabilities.isFilesSharingPublicExpireDateEnforceEnabled = capabilities.isFilesSharingPublicExpireDateEnforceEnabled
+                resultCapabilities.filesSharingPublicExpireDateDays = capabilities.filesSharingPublicExpireDateDays
+                resultCapabilities.isFilesSharingPublicPasswordEnforced = capabilities.isFilesSharingPublicPasswordEnforced
+                resultCapabilities.isFilesSharingAllowUserSendMail = capabilities.isFilesSharingAllowUserSendMail
+                resultCapabilities.isFilesSharingUserExpireDate = capabilities.isFilesSharingUserExpireDate
+                resultCapabilities.isFilesSharingGroupEnabled = capabilities.isFilesSharingGroupEnabled
+                resultCapabilities.isFilesSharingGroupExpireDate = capabilities.isFilesSharingGroupExpireDate
+                resultCapabilities.isFilesSharingFederationAllowUserSendShares = capabilities.isFilesSharingFederationAllowUserSendShares
+                resultCapabilities.isFilesSharingFederationAllowUserReceiveShares = capabilities.isFilesSharingFederationAllowUserReceiveShares
+                resultCapabilities.isFilesSharingFederationExpireDate = capabilities.isFilesSharingFederationExpireDate
+                resultCapabilities.isFileSharingShareByMailEnabled = capabilities.isFileSharingShareByMailEnabled
+                resultCapabilities.isFileSharingShareByMailPassword = capabilities.isFileSharingShareByMailPassword
+                resultCapabilities.isFileSharingShareByMailUploadFilesDrop = capabilities.isFileSharingShareByMailUploadFilesDrop
                 
                 if result == nil {
                     realm.add(resultCapabilities)
                 }
+                
+                
             }
         } catch let error {
             print("[LOG] Could not write to database: ", error)
@@ -1952,43 +1978,50 @@ class NCManageDatabase: NSObject {
         }
     }
     
-    func createTableMedia(_ metadatas: [tableMetadata], lteDate: Date, gteDate: Date,account: String) -> (differenceSizeInsert: Int64, differenceNumInsert: Int64) {
+    func createTableMedia(_ metadatas: [tableMetadata], lteDate: Date, gteDate: Date,account: String) -> (isDifferent: Bool, newInsert: Int) {
 
         let realm = try! Realm()
         realm.refresh()
         
-        var sizeDelete: Int64 = 0
-        var sizeInsert: Int64 = 0
-        var numDelete: Int64 = 0
-        var numInsert: Int64 = 0
-        var differenceSizeInsert: Int64 = 0
-        var differenceNumInsert: Int64 = 0
-
+        var numDelete: Int = 0
+        var numInsert: Int = 0
+        
+        var etagsDelete = [String]()
+        var etagsInsert = [String]()
+        
+        var isDifferent: Bool = false
+        var newInsert: Int = 0
+        
         do {
             try realm.write {
-                // DELETE ALL
+                
+                // DELETE
                 let results = realm.objects(tableMedia.self).filter("account = %@ AND date >= %@ AND date <= %@", account, gteDate, lteDate)
-                for resul in results {
-                    sizeDelete = sizeDelete + Int64(resul.size)
-                    numDelete += 1
-                }
-                realm.delete(results)
-                // INSERT ALL
+                etagsDelete = Array(results.map { $0.etag })
+                numDelete = results.count
+                
+                // INSERT
                 let photos = Array(metadatas.map { tableMedia.init(value:$0) })
-                for photo in photos {
-                    sizeInsert = sizeInsert + Int64(photo.size)
-                    numInsert += 1
+                etagsInsert = Array(photos.map { $0.etag })
+                numInsert = photos.count
+                
+                // CALCULATE DIFFERENT RETURN
+                if etagsDelete.count == etagsInsert.count && etagsDelete.sorted() == etagsInsert.sorted() {
+                    isDifferent = false
+                } else {
+                    isDifferent = true
+                    newInsert = numInsert - numDelete
+                    
+                    realm.delete(results)
+                    realm.add(photos, update: true)
                 }
-                realm.add(photos, update: true)
-                differenceSizeInsert = sizeInsert - sizeDelete
-                differenceNumInsert = numInsert - numDelete
             }
         } catch let error {
             print("[LOG] Could not write to database: ", error)
             realm.cancelWrite()
         }
         
-        return(differenceSizeInsert, differenceNumInsert)
+        return(isDifferent, newInsert)
     }
     
     @objc func getTableMediaDate(account: String, order: ComparisonResult) -> Date {
@@ -2441,13 +2474,20 @@ class NCManageDatabase: NSObject {
         }
     }
     
-    @objc func deleteTrash(filePath: String, account: String) {
+    @objc func deleteTrash(filePath: String?, account: String) {
         
         let realm = try! Realm()
-        
+        var predicate = NSPredicate()
+
         realm.beginWrite()
         
-        let results = realm.objects(tableTrash.self).filter("account = %@ AND filePath = %@", account, filePath)
+        if filePath == nil {
+            predicate = NSPredicate(format: "account == %@", account)
+        } else {
+            predicate = NSPredicate(format: "account = %@ AND filePath = %@", account, filePath!)
+        }
+        
+        let results = realm.objects(tableTrash.self).filter(predicate)
         realm.delete(results)
         
         do {
@@ -2465,11 +2505,8 @@ class NCManageDatabase: NSObject {
         realm.beginWrite()
         
         if fileID == nil {
-            
             predicate = NSPredicate(format: "account == %@", account)
-            
         } else {
-            
             predicate = NSPredicate(format: "account = %@ AND fileID = %@", account, fileID!)
         }
         

+ 1 - 2
iOSClient/Favorites/CCFavorites.h

@@ -35,7 +35,7 @@
 
 @class tableMetadata;
 
-@interface CCFavorites : UIViewController <UITableViewDataSource, UITableViewDelegate, UIDocumentInteractionControllerDelegate, UIActionSheetDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate, MGSwipeTableCellDelegate>
+@interface CCFavorites : UIViewController <UITableViewDataSource, UITableViewDelegate, UIActionSheetDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate, MGSwipeTableCellDelegate, UIViewControllerPreviewingDelegate>
 
 @property (nonatomic, weak) IBOutlet UITableView *tableView;
 
@@ -47,7 +47,6 @@
 @property (nonatomic, weak) CCDetail *detailViewController;
 
 - (void)shouldPerformSegue:(tableMetadata *)metadata;
-- (void)openIn:(tableMetadata *)metadata;
 - (void)reloadDatasource:(NSString *)fileID action:(NSInteger)action;
 - (void)listingFavorites;
 

+ 44 - 40
iOSClient/Favorites/CCFavorites.m

@@ -78,6 +78,12 @@
     self.tableView.emptyDataSetSource = self;
     self.tableView.delegate = self;
     
+    // Register for 3D Touch Previewing if available
+    if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)] && (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable))
+    {
+        [self registerForPreviewingWithDelegate:self sourceView:self.view];
+    }
+    
     // calculate _serverUrl
     if (!_serverUrl)
         _serverUrl = nil;
@@ -136,7 +142,7 @@
 
 - (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView
 {
-    return [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"favoriteNoFiles"] multiplier:1 color:[NCBrandColor sharedInstance].yellowFavorite];
+    return [CCGraphics changeThemingColorImage:[UIImage imageNamed:@"favorite"] width:300 height:300 color:[NCBrandColor sharedInstance].yellowFavorite];
 }
 
 - (NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView
@@ -252,27 +258,6 @@
     }];
 }
 
-#pragma --------------------------------------------------------------------------------------------
-#pragma mark ==== Open in... ====
-#pragma --------------------------------------------------------------------------------------------
-
-- (void)openIn:(tableMetadata *)metadata
-{
-    NSURL *url = [NSURL fileURLWithPath:[CCUtility getDirectoryProviderStorageFileID:metadata.fileID fileNameView:metadata.fileNameView]];
-        
-    docController = [UIDocumentInteractionController interactionControllerWithURL:url];
-    docController.delegate = self;
-        
-    NSIndexPath *indexPath = [sectionDataSource.fileIDIndexPath objectForKey:metadata.fileID];
-    CCCellMain *cell = [self.tableView cellForRowAtIndexPath:indexPath];
-
-    if (cell) {
-        [docController presentOptionsMenuFromRect:cell.frame inView:self.tableView animated:YES];
-    } else {
-        [docController presentOptionsMenuFromRect:self.view.frame inView:self.view animated:YES];
-    }
-}
-
 - (void)tapActionConnectionMounted:(UITapGestureRecognizer *)tapGesture
 {
     CGPoint location = [tapGesture locationInView:self.tableView];
@@ -335,6 +320,39 @@
     [self presentViewController:alertController animated:YES completion:nil];
 }
 
+#pragma mark -
+#pragma --------------------------------------------------------------------------------------------
+#pragma mark ===== Peek & Pop  =====
+#pragma --------------------------------------------------------------------------------------------
+
+- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location
+{
+    CGPoint convertedLocation = [self.view convertPoint:location toView:self.tableView];
+    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:convertedLocation];
+    tableMetadata *metadata = [[NCMainCommon sharedInstance] getMetadataFromSectionDataSourceIndexPath:indexPath sectionDataSource:sectionDataSource];
+    
+    CCCellMain *cell = [self.tableView cellForRowAtIndexPath:indexPath];
+    
+    if (cell) {
+        previewingContext.sourceRect = cell.frame;
+        CCPeekPop *viewController = [[UIStoryboard storyboardWithName:@"CCPeekPop" bundle:nil] instantiateViewControllerWithIdentifier:@"PeekPopImagePreview"];
+        
+        viewController.metadata = metadata;
+        viewController.imageFile = cell.file.image;
+        
+        return viewController;
+    }
+    
+    return nil;
+}
+
+- (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit
+{
+    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:previewingContext.sourceRect.origin];
+    
+    [self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
+}
+
 #pragma mark -
 #pragma --------------------------------------------------------------------------------------------
 #pragma mark ===== menu action : Favorite, More, Delete [swipe] =====
@@ -473,27 +491,13 @@
         [actionSheet addButtonWithTitle:NSLocalizedString(@"_open_in_", nil) image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"openFile"] multiplier:2 color:[NCBrandColor sharedInstance].brandElement] backgroundColor:[NCBrandColor sharedInstance].backgroundView height: 50.0 type:AHKActionSheetButtonTypeDefault handler:^(AHKActionSheet *as) {
             [self.tableView setEditing:NO animated:YES];
             
-            if ([CCUtility fileProviderStorageExists:metadata.fileID fileNameView:metadata.fileNameView]) {
-                [self openIn:metadata];
-            } else {
-                
-                metadata.session = k_download_session;
-                metadata.sessionError = @"";
-                metadata.sessionSelector = selectorOpenIn;
-                metadata.status = k_metadataStatusWaitDownload;
-                
-                // Add Metadata for Download
-                tableMetadata *metadataForDownload = [[NCManageDatabase sharedInstance] addMetadata:metadata];
-                [[CCNetworking sharedNetworking] downloadFile:metadataForDownload taskStatus:k_taskStatusResume];
-                
-                [[NCMainCommon sharedInstance] reloadDatasourceWithServerUrl:metadata.serverUrl fileID:metadataForDownload.fileID action:k_action_MOD];
-            }
+            [[NCMainCommon sharedInstance] downloadOpenInMetadata:metadata];
         }];
     }
     
     // Delete
     [actionSheet addButtonWithTitle:NSLocalizedString(@"_delete_", nil)
-                              image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"delete"] multiplier:2 color:[UIColor redColor]]
+                              image:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"trash"] width:50 height:50 color:[UIColor redColor]]
                     backgroundColor:[NCBrandColor sharedInstance].backgroundView
                              height:50.0
                                type:AHKActionSheetButtonTypeDestructive
@@ -605,7 +609,7 @@
         // LEFT : configure ONLY Root Favorites : Remove file/folder Favorites
         if (_serverUrl == nil) {
             
-            ((CCCellMain *)cell).leftButtons = @[[MGSwipeButton buttonWithTitle:@"" icon:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"favorite"] multiplier:1 color:[UIColor whiteColor]] backgroundColor:[NCBrandColor sharedInstance].yellowFavorite padding:25]];
+            ((CCCellMain *)cell).leftButtons = @[[MGSwipeButton buttonWithTitle:@"" icon:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"favorite"] width:50 height:50 color:[UIColor whiteColor]] backgroundColor:[NCBrandColor sharedInstance].yellowFavorite padding:25]];
             ((CCCellMain *)cell).leftExpansion.buttonIndex = 0;
             ((CCCellMain *)cell).leftExpansion.fillOnTrigger = NO;
             
@@ -615,7 +619,7 @@
         }
         
         // RIGHT
-        ((CCCellMain *)cell).rightButtons = @[[MGSwipeButton buttonWithTitle:@"" icon:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"delete"] multiplier:2 color:[UIColor whiteColor]] backgroundColor:[UIColor redColor] padding:25]];
+        ((CCCellMain *)cell).rightButtons = @[[MGSwipeButton buttonWithTitle:@"" icon:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"trash"] width:50 height:50 color:[UIColor whiteColor]] backgroundColor:[UIColor redColor] padding:25]];
         
         ((CCCellMain *)cell).rightExpansion.buttonIndex = 0;
         ((CCCellMain *)cell).rightExpansion.fillOnTrigger = NO;

+ 1 - 12
iOSClient/Images.xcassets/acknowledgements.imageset/Contents.json

@@ -2,18 +2,7 @@
   "images" : [
     {
       "idiom" : "universal",
-      "filename" : "acknowledgements.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "acknowledgements@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "acknowledgements@3x.png",
-      "scale" : "3x"
+      "filename" : "acknowledgements.pdf"
     }
   ],
   "info" : {

BIN
iOSClient/Images.xcassets/acknowledgements.imageset/acknowledgements.pdf


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


BIN
iOSClient/Images.xcassets/acknowledgements.imageset/acknowledgements@2x.png


BIN
iOSClient/Images.xcassets/acknowledgements.imageset/acknowledgements@3x.png


+ 4 - 12
iOSClient/Images.xcassets/activity.imageset/Contents.json

@@ -2,22 +2,14 @@
   "images" : [
     {
       "idiom" : "universal",
-      "filename" : "activity.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "activity@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "activity@3x.png",
-      "scale" : "3x"
+      "filename" : "activity.pdf"
     }
   ],
   "info" : {
     "version" : 1,
     "author" : "xcode"
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
   }
 }

BIN
iOSClient/Images.xcassets/activity.imageset/activity.pdf


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


BIN
iOSClient/Images.xcassets/activity.imageset/activity@2x.png


BIN
iOSClient/Images.xcassets/activity.imageset/activity@3x.png


BIN
iOSClient/Images.xcassets/activityNoRecord.imageset/activityNoRecord@2x.png


+ 15 - 0
iOSClient/Images.xcassets/audioPlay.imageset/Contents.json

@@ -0,0 +1,15 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "play.pdf"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
+  }
+}

BIN
iOSClient/Images.xcassets/audioPlay.imageset/play.pdf


+ 15 - 0
iOSClient/Images.xcassets/audioStop.imageset/Contents.json

@@ -0,0 +1,15 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "stop.pdf"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
+  }
+}

BIN
iOSClient/Images.xcassets/audioStop.imageset/stop.pdf


+ 4 - 12
iOSClient/Images.xcassets/autoUpload.imageset/Contents.json

@@ -2,22 +2,14 @@
   "images" : [
     {
       "idiom" : "universal",
-      "filename" : "autoUpload.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "autoUpload@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "autoUpload@3x.png",
-      "scale" : "3x"
+      "filename" : "autoUpload.pdf"
     }
   ],
   "info" : {
     "version" : 1,
     "author" : "xcode"
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
   }
 }

BIN
iOSClient/Images.xcassets/autoUpload.imageset/autoUpload.pdf


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


BIN
iOSClient/Images.xcassets/autoUpload.imageset/autoUpload@2x.png


BIN
iOSClient/Images.xcassets/autoUpload.imageset/autoUpload@3x.png


+ 0 - 21
iOSClient/Images.xcassets/button1000x200.imageset/Contents.json

@@ -1,21 +0,0 @@
-{
-  "images" : [
-    {
-      "idiom" : "universal",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "button1000x200@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "scale" : "3x"
-    }
-  ],
-  "info" : {
-    "version" : 1,
-    "author" : "xcode"
-  }
-}

BIN
iOSClient/Images.xcassets/button1000x200.imageset/button1000x200@2x.png


+ 0 - 21
iOSClient/Images.xcassets/button500x100.imageset/Contents.json

@@ -1,21 +0,0 @@
-{
-  "images" : [
-    {
-      "idiom" : "universal",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "button500x100@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "scale" : "3x"
-    }
-  ],
-  "info" : {
-    "version" : 1,
-    "author" : "xcode"
-  }
-}

BIN
iOSClient/Images.xcassets/button500x100.imageset/button500x100@2x.png


+ 15 - 0
iOSClient/Images.xcassets/cancel.imageset/Contents.json

@@ -0,0 +1,15 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "cancel.pdf"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
+  }
+}

BIN
iOSClient/Images.xcassets/cancel.imageset/cancel.pdf


+ 4 - 12
iOSClient/Images.xcassets/checkedNo.imageset/Contents.json

@@ -2,22 +2,14 @@
   "images" : [
     {
       "idiom" : "universal",
-      "filename" : "checkedNo.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "checkedNo@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "checkedNo@3x.png",
-      "scale" : "3x"
+      "filename" : "checkedNo.pdf"
     }
   ],
   "info" : {
     "version" : 1,
     "author" : "xcode"
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
   }
 }

BIN
iOSClient/Images.xcassets/checkedNo.imageset/checkedNo.pdf


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


BIN
iOSClient/Images.xcassets/checkedNo.imageset/checkedNo@2x.png


BIN
iOSClient/Images.xcassets/checkedNo.imageset/checkedNo@3x.png


+ 1 - 12
iOSClient/Images.xcassets/checkedYes.imageset/Contents.json

@@ -2,18 +2,7 @@
   "images" : [
     {
       "idiom" : "universal",
-      "filename" : "checkedYes.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "checkedYes@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "checkedYes@3x.png",
-      "scale" : "3x"
+      "filename" : "checkedYes.pdf"
     }
   ],
   "info" : {

BIN
iOSClient/Images.xcassets/checkedYes.imageset/checkedYes.pdf


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


BIN
iOSClient/Images.xcassets/checkedYes.imageset/checkedYes@2x.png


BIN
iOSClient/Images.xcassets/checkedYes.imageset/checkedYes@3x.png


+ 15 - 0
iOSClient/Images.xcassets/closeCircle.imageset/Contents.json

@@ -0,0 +1,15 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "closeCircle.pdf"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
+  }
+}

+ 51 - 0
iOSClient/Images.xcassets/closeCircle.imageset/closeCircle.pdf

@@ -0,0 +1,51 @@
+%PDF-1.4
+%Óëéá
+1 0 obj
+<</Creator (Chromium)
+/Producer (Skia/PDF m66)
+/CreationDate (D:20190307161004+00'00')
+/ModDate (D:20190307161004+00'00')>>
+endobj
+2 0 obj
+<</Filter /FlateDecode
+/Length 172>> stream
+xœ]ŽKÂ0D÷>…×H;mH{Ö¬8@Åg‘"÷—HMµÍxÞL¢,X[ŧái¦ÉWØû<ÓiÃwL5†Tᶼ;__ð8òLšCBH*FÞ‡>CIgÈDöoŒ£«�øËxú×àZ[ó°5…4Ú,r¶Á�6)4„^F<ÜB™]È�«ëÊ|T-kÍ�O/ìÇ_Å\Ûuu¸¿w¡]èˆõè\O[
+endstream
+endobj
+3 0 obj
+<</Type /Catalog
+/Pages 4 0 R>>
+endobj
+4 0 obj
+<</Type /Pages
+/Count 1
+/Kids [5 0 R]>>
+endobj
+5 0 obj
+<</Type /Page
+/Resources <</ProcSets [/PDF /Text /ImageB /ImageC /ImageI]
+/ExtGState <</G0 6 0 R>>>>
+/MediaBox [0 0 300 300]
+/Contents 2 0 R
+/Parent 4 0 R>>
+endobj
+6 0 obj
+<</ca 1
+/BM /Normal>>
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000154 00000 n 
+0000000396 00000 n 
+0000000443 00000 n 
+0000000498 00000 n 
+0000000670 00000 n 
+trailer
+<</Size 7
+/Root 3 0 R
+/Info 1 0 R>>
+startxref
+707
+%%EOF

+ 1 - 1
iOSClient/Images.xcassets/document_menu.imageset/Contents.json → iOSClient/Images.xcassets/create_file_document.imageset/Contents.json

@@ -7,7 +7,7 @@
     },
     {
       "idiom" : "universal",
-      "filename" : "document_menu@2x.png",
+      "filename" : "create_file_document@2x.png",
       "scale" : "2x"
     },
     {

+ 0 - 0
iOSClient/Images.xcassets/document.imageset/document.png → iOSClient/Images.xcassets/create_file_document.imageset/create_file_document@2x.png


+ 0 - 0
iOSClient/Images.xcassets/document_menu.imageset/document_menu.png → iOSClient/Images.xcassets/create_file_document.imageset/document_menu.png


+ 0 - 0
iOSClient/Images.xcassets/document_menu.imageset/document_menu@3x.png → iOSClient/Images.xcassets/create_file_document.imageset/document_menu@3x.png


+ 1 - 1
iOSClient/Images.xcassets/file_ppt_menu.imageset/Contents.json → iOSClient/Images.xcassets/create_file_ppt.imageset/Contents.json

@@ -7,7 +7,7 @@
     },
     {
       "idiom" : "universal",
-      "filename" : "file_ppt_menu@2x.png",
+      "filename" : "create_file_ppt@2x.png",
       "scale" : "2x"
     },
     {

+ 0 - 0
iOSClient/Images.xcassets/file_ppt.imageset/file_ppt.png → iOSClient/Images.xcassets/create_file_ppt.imageset/create_file_ppt@2x.png


+ 0 - 0
iOSClient/Images.xcassets/file_ppt_menu.imageset/file_ppt_menu.png → iOSClient/Images.xcassets/create_file_ppt.imageset/file_ppt_menu.png


+ 0 - 0
iOSClient/Images.xcassets/file_ppt_menu.imageset/file_ppt_menu@3x.png → iOSClient/Images.xcassets/create_file_ppt.imageset/file_ppt_menu@3x.png


+ 1 - 1
iOSClient/Images.xcassets/file_xls_menu.imageset/Contents.json → iOSClient/Images.xcassets/create_file_xls.imageset/Contents.json

@@ -7,7 +7,7 @@
     },
     {
       "idiom" : "universal",
-      "filename" : "file_xls_menu@2x.png",
+      "filename" : "create_file_xls@2x.png",
       "scale" : "2x"
     },
     {

+ 0 - 0
iOSClient/Images.xcassets/file_xls.imageset/file_xls.png → iOSClient/Images.xcassets/create_file_xls.imageset/create_file_xls@2x.png


+ 0 - 0
iOSClient/Images.xcassets/file_xls_menu.imageset/file_xls_menu.png → iOSClient/Images.xcassets/create_file_xls.imageset/file_xls_menu.png


+ 0 - 0
iOSClient/Images.xcassets/file_xls_menu.imageset/file_xls_menu@3x.png → iOSClient/Images.xcassets/create_file_xls.imageset/file_xls_menu@3x.png


+ 0 - 0
iOSClient/Images.xcassets/delete.imageset/Contents.json → iOSClient/Images.xcassets/deletePhotoBrowser.imageset/Contents.json


+ 0 - 0
iOSClient/Images.xcassets/delete.imageset/delete.png → iOSClient/Images.xcassets/deletePhotoBrowser.imageset/delete.png


+ 0 - 0
iOSClient/Images.xcassets/delete.imageset/delete@2x.png → iOSClient/Images.xcassets/deletePhotoBrowser.imageset/delete@2x.png


+ 0 - 0
iOSClient/Images.xcassets/delete.imageset/delete@3x.png → iOSClient/Images.xcassets/deletePhotoBrowser.imageset/delete@3x.png


+ 15 - 0
iOSClient/Images.xcassets/details.imageset/Contents.json

@@ -0,0 +1,15 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "filename" : "details.pdf"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
+  }
+}

BIN
iOSClient/Images.xcassets/details.imageset/details.pdf


+ 1 - 10
iOSClient/Images.xcassets/disclosureIndicator.imageset/Contents.json

@@ -2,16 +2,7 @@
   "images" : [
     {
       "idiom" : "universal",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "disclosureIndicator@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "scale" : "3x"
+      "filename" : "disclosureIndicator@2x.png"
     }
   ],
   "info" : {

+ 4 - 12
iOSClient/Images.xcassets/document.imageset/Contents.json

@@ -2,22 +2,14 @@
   "images" : [
     {
       "idiom" : "universal",
-      "filename" : "document.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "document@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "document@3x.png",
-      "scale" : "3x"
+      "filename" : "document.pdf"
     }
   ],
   "info" : {
     "version" : 1,
     "author" : "xcode"
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
   }
 }

+ 52 - 0
iOSClient/Images.xcassets/document.imageset/document.pdf

@@ -0,0 +1,52 @@
+%PDF-1.4
+%Óëéá
+1 0 obj
+<</Creator (Chromium)
+/Producer (Skia/PDF m66)
+/CreationDate (D:20190305212840+00'00')
+/ModDate (D:20190305212840+00'00')>>
+endobj
+2 0 obj
+<</Filter /FlateDecode
+/Length 196>> stream
+xœ]�M!…÷=E×&"åw8Á¬uã&:.õþ‰¯€Ñ¡ï•~¶˜{AðÖò²ÑƒìHt=/tÞñ»2™ýuÀ�››”…M‘‰O3ÿí<W:Ì–×9Yxƒ:ƒcuø–D^`j79ŒÌýDäÖA1ñÝUu
+¹„ßc=k|à °àÞ:RéF�=$ø«VmƒÂˆ~	DA¬ˆ¹UzL£^´ƒƒT4Ñâ�26šTªŠïÌ× +1ßIL‚
+endstream
+endobj
+3 0 obj
+<</Type /Catalog
+/Pages 4 0 R>>
+endobj
+4 0 obj
+<</Type /Pages
+/Count 1
+/Kids [5 0 R]>>
+endobj
+5 0 obj
+<</Type /Page
+/Resources <</ProcSets [/PDF /Text /ImageB /ImageC /ImageI]
+/ExtGState <</G0 6 0 R>>>>
+/MediaBox [0 0 300 300]
+/Contents 2 0 R
+/Parent 4 0 R>>
+endobj
+6 0 obj
+<</ca 1
+/BM /Normal>>
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000154 00000 n 
+0000000420 00000 n 
+0000000467 00000 n 
+0000000522 00000 n 
+0000000694 00000 n 
+trailer
+<</Size 7
+/Root 3 0 R
+/Info 1 0 R>>
+startxref
+731
+%%EOF

BIN
iOSClient/Images.xcassets/document.imageset/document@2x.png


BIN
iOSClient/Images.xcassets/document.imageset/document@3x.png


BIN
iOSClient/Images.xcassets/document_menu.imageset/document_menu@2x.png


+ 4 - 12
iOSClient/Images.xcassets/e2eReadPassphrase.imageset/Contents.json

@@ -2,22 +2,14 @@
   "images" : [
     {
       "idiom" : "universal",
-      "filename" : "e2eReadPassphrase.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "e2eReadPassphrase@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "e2eReadPassphrase@3x.png",
-      "scale" : "3x"
+      "filename" : "e2eReadPassphrase.pdf"
     }
   ],
   "info" : {
     "version" : 1,
     "author" : "xcode"
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
   }
 }

BIN
iOSClient/Images.xcassets/e2eReadPassphrase.imageset/e2eReadPassphrase.pdf


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


BIN
iOSClient/Images.xcassets/e2eReadPassphrase.imageset/e2eReadPassphrase@2x.png


BIN
iOSClient/Images.xcassets/e2eReadPassphrase.imageset/e2eReadPassphrase@3x.png


+ 4 - 12
iOSClient/Images.xcassets/exit.imageset/Contents.json

@@ -2,22 +2,14 @@
   "images" : [
     {
       "idiom" : "universal",
-      "filename" : "exit.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "exit@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "exit@3x.png",
-      "scale" : "3x"
+      "filename" : "exit.pdf"
     }
   ],
   "info" : {
     "version" : 1,
     "author" : "xcode"
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
   }
 }

+ 51 - 0
iOSClient/Images.xcassets/exit.imageset/exit.pdf

@@ -0,0 +1,51 @@
+%PDF-1.4
+%Óëéá
+1 0 obj
+<</Creator (Chromium)
+/Producer (Skia/PDF m66)
+/CreationDate (D:20190307154558+00'00')
+/ModDate (D:20190307154558+00'00')>>
+endobj
+2 0 obj
+<</Filter /FlateDecode
+/Length 137>> stream
+xœUNË!¼ÏWôl²ØÂÊÂxöäl|Xõÿ[Ô…m™ig„X{½3Ížà±óºà¼£‡N%¹éPÕ
©|dº½!#‰wêÐò´ #º*H”]ÌVIYXq]ŠËÚlqÅæñ6	5›åÇÎÙÅT:’éÚÒw¼yïŽ+NÚOÇ6
+endstream
+endobj
+3 0 obj
+<</Type /Catalog
+/Pages 4 0 R>>
+endobj
+4 0 obj
+<</Type /Pages
+/Count 1
+/Kids [5 0 R]>>
+endobj
+5 0 obj
+<</Type /Page
+/Resources <</ProcSets [/PDF /Text /ImageB /ImageC /ImageI]
+/ExtGState <</G0 6 0 R>>>>
+/MediaBox [0 0 300 300]
+/Contents 2 0 R
+/Parent 4 0 R>>
+endobj
+6 0 obj
+<</ca 1
+/BM /Normal>>
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000154 00000 n 
+0000000361 00000 n 
+0000000408 00000 n 
+0000000463 00000 n 
+0000000635 00000 n 
+trailer
+<</Size 7
+/Root 3 0 R
+/Info 1 0 R>>
+startxref
+672
+%%EOF

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


BIN
iOSClient/Images.xcassets/exit.imageset/exit@2x.png


BIN
iOSClient/Images.xcassets/exit.imageset/exit@3x.png


+ 1 - 12
iOSClient/Images.xcassets/favorite.imageset/Contents.json

@@ -2,18 +2,7 @@
   "images" : [
     {
       "idiom" : "universal",
-      "filename" : "favorite.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "favorite@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "favorite@3x.png",
-      "scale" : "3x"
+      "filename" : "favorite.pdf"
     }
   ],
   "info" : {

BIN
iOSClient/Images.xcassets/favorite.imageset/favorite.pdf


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


BIN
iOSClient/Images.xcassets/favorite.imageset/favorite@2x.png


BIN
iOSClient/Images.xcassets/favorite.imageset/favorite@3x.png


+ 0 - 21
iOSClient/Images.xcassets/favoriteNoFiles.imageset/Contents.json

@@ -1,21 +0,0 @@
-{
-  "images" : [
-    {
-      "idiom" : "universal",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "favoriteNoFiles@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "scale" : "3x"
-    }
-  ],
-  "info" : {
-    "version" : 1,
-    "author" : "xcode"
-  }
-}

BIN
iOSClient/Images.xcassets/favoriteNoFiles.imageset/favoriteNoFiles@2x.png


+ 4 - 12
iOSClient/Images.xcassets/file.imageset/Contents.json

@@ -2,22 +2,14 @@
   "images" : [
     {
       "idiom" : "universal",
-      "filename" : "file.png",
-      "scale" : "1x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "file@2x.png",
-      "scale" : "2x"
-    },
-    {
-      "idiom" : "universal",
-      "filename" : "file@3x.png",
-      "scale" : "3x"
+      "filename" : "file.pdf"
     }
   ],
   "info" : {
     "version" : 1,
     "author" : "xcode"
+  },
+  "properties" : {
+    "preserves-vector-representation" : true
   }
 }

+ 51 - 0
iOSClient/Images.xcassets/file.imageset/file.pdf

@@ -0,0 +1,51 @@
+%PDF-1.4
+%Óëéá
+1 0 obj
+<</Creator (Chromium)
+/Producer (Skia/PDF m66)
+/CreationDate (D:20190305212358+00'00')
+/ModDate (D:20190305212358+00'00')>>
+endobj
+2 0 obj
+<</Filter /FlateDecode
+/Length 145>> stream
+xœ]ŽKÂ0D÷>Ŭ‘q>J8A×eÃ*(‹‰r‰IRTD,Ûo¬q…e•Å[‹i‘—ØMÔ\or=àÉ©f“bsïD»‰9c/—“u–Ó`1¿Å™ÅÂî�I°õø&"&a„Ò!¥3OB߈h7T›úN¥Ò×E­áw­«æÕ¬|·l)ò�»ŒŒîÞ2S
+endstream
+endobj
+3 0 obj
+<</Type /Catalog
+/Pages 4 0 R>>
+endobj
+4 0 obj
+<</Type /Pages
+/Count 1
+/Kids [5 0 R]>>
+endobj
+5 0 obj
+<</Type /Page
+/Resources <</ProcSets [/PDF /Text /ImageB /ImageC /ImageI]
+/ExtGState <</G0 6 0 R>>>>
+/MediaBox [0 0 300 300]
+/Contents 2 0 R
+/Parent 4 0 R>>
+endobj
+6 0 obj
+<</ca 1
+/BM /Normal>>
+endobj
+xref
+0 7
+0000000000 65535 f 
+0000000015 00000 n 
+0000000154 00000 n 
+0000000369 00000 n 
+0000000416 00000 n 
+0000000471 00000 n 
+0000000643 00000 n 
+trailer
+<</Size 7
+/Root 3 0 R
+/Info 1 0 R>>
+startxref
+680
+%%EOF

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


BIN
iOSClient/Images.xcassets/file.imageset/file@2x.png


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