diff options
author | marinofaggiana <marino@marinofaggiana.com> | 2020-07-29 11:36:29 +0300 |
---|---|---|
committer | marinofaggiana <marino@marinofaggiana.com> | 2020-07-29 11:36:29 +0300 |
commit | da3dec59f351bad1f27e79486af7fba022522299 (patch) | |
tree | f013a55caa6d42c18e58a90faf1528c3663600d6 | |
parent | f635e64a42768d112ac6dd7907a59f84f6c2b060 (diff) | |
parent | d068e8104110cdbabc2e3f1b7b090144bdc2f361 (diff) |
Merge branch 'develop'v3.0.2
229 files changed, 2348 insertions, 1716 deletions
@@ -1,16 +1,16 @@ -github "nextcloud/ios-communication-library" "v0.74" -github "tilltue/TLPhotoPicker" "2.0.11" +github "nextcloud/ios-communication-library" "v0.75" +github "tilltue/TLPhotoPicker" "2.0.12" github "kishikawakatsumi/UICKeyChainStore" "v2.1.2" github "MortimerGoro/MGSwipeTableCell" "1.6.8" github "dzenbot/DZNEmptyDataSet" "v1.8.1" github "jdg/MBProgressHUD" "1.1.0" -github "realm/realm-cocoa" +github "realm/realm-cocoa" "v5.3.2" github "SVGKit/SVGKit" "3.x" github "WeTransfer/WeScan" "1.2.0" github "malcommac/SwiftRichString" github "yannickl/QRCodeReader.swift" "10.1.1" github "weichsel/ZIPFoundation" "0.9.10" -github "rechsteiner/Parchment" "v1.7.0" +github "rechsteiner/Parchment" "v2.4.0" github "WenchaoD/FSCalendar" "2.8.0" github "AssistoLab/DropDown" "v2.3.13" github "krzyzanowskim/OpenSSL" "1.0.218" @@ -19,7 +19,7 @@ github "scenee/FloatingPanel" github "ivanbruel/MarkdownKit" github "getsentry/sentry-cocoa" github "FabrizioBrancati/Queuer" +github "xmartlabs/XLForm" ~> 4.1 github "https://github.com/marinofaggiana/KTVHTTPCache" "2.0.2" -github "https://github.com/marinofaggiana/XLForm" "master" github "https://github.com/marinofaggiana/TOPasscodeViewController" "0.0.7" diff --git a/Cartfile.resolved b/Cartfile.resolved index 8abced9e3..0d34e859b 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,14 +1,14 @@ -github "Alamofire/Alamofire" "5.2.1" +github "Alamofire/Alamofire" "5.2.2" github "AssistoLab/DropDown" "v2.3.13" github "CocoaLumberjack/CocoaLumberjack" "3.6.1" github "FabrizioBrancati/Queuer" "2.1.1" github "MortimerGoro/MGSwipeTableCell" "1.6.8" -github "SVGKit/SVGKit" "2a4068f0ea546dcd82f7e4dd9aa9026c0a0a2235" +github "SVGKit/SVGKit" "9240977515c04053f8c96c9dfdb764dc7b98b9ba" github "SwiftyJSON/SwiftyJSON" "5.0.0" github "WeTransfer/WeScan" "1.2.0" github "WenchaoD/FSCalendar" "2.8.0" github "dzenbot/DZNEmptyDataSet" "v1.8.1" -github "getsentry/sentry-cocoa" "5.1.8" +github "getsentry/sentry-cocoa" "5.1.10" github "huri000/QuickLayout" "3.0.0" github "huri000/SwiftEntryKit" "1.2.3" github "ivanbruel/MarkdownKit" "1.6" @@ -18,12 +18,12 @@ github "krzyzanowskim/OpenSSL" "1.0.218" github "malcommac/SwiftRichString" "3.7.2" github "marinofaggiana/KTVHTTPCache" "2.0.2" github "marinofaggiana/TOPasscodeViewController" "0.0.7" -github "marinofaggiana/XLForm" "eb9381ad8129f60402bf412250fb31b95a628a08" -github "nextcloud/ios-communication-library" "v0.74" -github "realm/realm-cocoa" "v5.2.0" -github "rechsteiner/Parchment" "v1.7.0" +github "nextcloud/ios-communication-library" "v0.75" +github "realm/realm-cocoa" "v5.3.2" +github "rechsteiner/Parchment" "v2.4.0" github "scenee/FloatingPanel" "v1.7.5" -github "tilltue/TLPhotoPicker" "2.0.11" +github "tilltue/TLPhotoPicker" "2.0.12" github "weichsel/ZIPFoundation" "0.9.10" +github "xmartlabs/XLForm" "4.1.0" github "yahoojapan/SwiftyXMLParser" "5.2.0" github "yannickl/QRCodeReader.swift" "10.1.1" diff --git a/Carthage/Checkouts/SVGKit/SVGKit.podspec b/Carthage/Checkouts/SVGKit/SVGKit.podspec index 6762af3d1..673dea9c9 100644 --- a/Carthage/Checkouts/SVGKit/SVGKit.podspec +++ b/Carthage/Checkouts/SVGKit/SVGKit.podspec @@ -17,13 +17,10 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/SVGKit/SVGKit.git', :tag => s.version.to_s } s.source_files = 'Source/*.{h,m}', 'Source/**/*.{h,m}' - s.ios.exclude_files = 'Source/AppKit additions/*.{h,m}', 'Source/Exporters/SVGKExporterNSImage.{h,m}' - s.tvos.exclude_files = 'Source/AppKit additions/*.{h,m}', 'Source/Exporters/SVGKExporterNSImage.{h,m}' - s.osx.exclude_files = 'Source/Exporters/SVGKExporterUIImage.{h,m}' + s.exclude_files = 'Source/include/*.h' s.libraries = 'xml2' s.framework = 'QuartzCore', 'CoreText' s.dependency 'CocoaLumberjack', '~> 3.0' - s.prefix_header_file = 'SVGKitLibrary/SVGKit-iOS/SVGKit-Prefix.pch' s.module_map = 'SVGKitLibrary/SVGKit-iOS/SVGKit.modulemap' s.requires_arc = true s.pod_target_xcconfig = { diff --git a/Carthage/Checkouts/SVGKit/SVGKitLibrary/SVGKit-iOS/SVGKit-Prefix.pch b/Carthage/Checkouts/SVGKit/SVGKitLibrary/SVGKit-iOS/SVGKit-Prefix.pch deleted file mode 100644 index ed3cd4d4c..000000000 --- a/Carthage/Checkouts/SVGKit/SVGKitLibrary/SVGKit-iOS/SVGKit-Prefix.pch +++ /dev/null @@ -1,31 +0,0 @@ -// -// Prefix header for all source files of the 'SVGKit-iOS' target in the 'SVGKit-iOS' project -// - -#ifdef __OBJC__ -#import <Foundation/Foundation.h> -#import <CocoaLumberjack/CocoaLumberjack.h> -#import "SVGKDefine.h" - -// These macro is only used inside framework project, does not expose to public header and effect user's define - -#define SVGKIT_LOG_CONTEXT 556 - -#define SVGKitLogError(frmt, ...) LOG_MAYBE(NO, LOG_LEVEL_DEF, DDLogFlagError, SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) -#define SVGKitLogWarn(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagWarning, SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) -#define SVGKitLogInfo(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagInfo, SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) -#define SVGKitLogDebug(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug, SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) -#define SVGKitLogVerbose(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) - -#if DEBUG -static const int ddLogLevel = DDLogLevelVerbose; -#else -static const int ddLogLevel = DDLogLevelWarning; -#endif - -#if SVGKIT_MAC -#define NSStringFromCGRect(rect) NSStringFromRect(rect) -#define NSStringFromCGSize(size) NSStringFromSize(size) -#define NSStringFromCGPoint(point) NSStringFromPoint(point) -#endif -#endif diff --git a/Carthage/Checkouts/SVGKit/Source/AppKit additions/SVGKImageRep.h b/Carthage/Checkouts/SVGKit/Source/AppKit additions/SVGKImageRep.h index d68c9de2d..2082a4411 100644 --- a/Carthage/Checkouts/SVGKit/Source/AppKit additions/SVGKImageRep.h +++ b/Carthage/Checkouts/SVGKit/Source/AppKit additions/SVGKImageRep.h @@ -6,6 +6,9 @@ // // +#import "SVGKDefine.h" + +#if SVGKIT_MAC #import <Cocoa/Cocoa.h> @class SVGKImage; @class SVGKSource; @@ -36,3 +39,5 @@ + (void)unloadSVGKImageRep; @end + +#endif /* SVGKIT_MAC */ diff --git a/Carthage/Checkouts/SVGKit/Source/AppKit additions/SVGKImageRep.m b/Carthage/Checkouts/SVGKit/Source/AppKit additions/SVGKImageRep.m index 4baf533c5..04204e48a 100644 --- a/Carthage/Checkouts/SVGKit/Source/AppKit additions/SVGKImageRep.m +++ b/Carthage/Checkouts/SVGKit/Source/AppKit additions/SVGKImageRep.m @@ -7,11 +7,12 @@ // #import "SVGKit.h" + +#if SVGKIT_MAC #import "SVGKSourceNSData.h" #import "SVGKSourceLocalFile.h" #import "SVGKSourceURL.h" #import "SVGKSourceString.h" -#import "SVGKFastImageView.h" #import "SVGKImageRep.h" #import "SVGKImage+CGContext.h" #include <tgmath.h> @@ -288,3 +289,5 @@ } @end + +#endif /* SVGKIT_MAC */ diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/CSSStyleDeclaration.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/CSSStyleDeclaration.m index 18e2135a2..6be5bc218 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/CSSStyleDeclaration.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/CSSStyleDeclaration.m @@ -5,6 +5,8 @@ #import "CSSPrimitiveValue.h" #import "CocoaLumberjack/DDFileLogger.h" +#import "SVGKDefine_Private.h" + @interface CSSStyleDeclaration() @property(nonatomic,strong) NSMutableDictionary* internalDictionaryOfStylesByCSSClass; diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/CSSValueList.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/CSSValueList.m index 665afcdc4..ebe542a71 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/CSSValueList.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/CSSValueList.m @@ -1,5 +1,6 @@ #import "CSSValueList.h" #import "CSSValue_ForSubclasses.h" +#import "SVGKDefine_Private.h" @interface CSSValueList() diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/Document.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/Document.m index f9ce5facd..0c2bc8c9a 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/Document.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/Core DOM/Document.m @@ -5,6 +5,8 @@ #import "NodeList+Mutable.h" // needed for access to underlying array, because SVG doesnt specify how lists are made mutable +#import "SVGKDefine_Private.h" + @implementation Document @synthesize doctype; diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGClipPathElement.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGClipPathElement.m index 96b25e5e9..7e9a1fb83 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGClipPathElement.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGClipPathElement.m @@ -4,6 +4,8 @@ #import "SVGHelperUtilities.h" +#import "SVGKDefine_Private.h" + @implementation SVGClipPathElement @synthesize clipPathUnits; diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGDocument.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGDocument.m index 28de3d59c..108a9d6fa 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGDocument.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGDocument.m @@ -13,6 +13,8 @@ #import "NamedNodeMap_Iterable.h" // needed for the allPrefixesByNamespace implementation +#import "SVGKDefine_Private.h" + @implementation SVGDocument diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGHelperUtilities.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGHelperUtilities.m index 6e7f33895..291c9a975 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGHelperUtilities.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGHelperUtilities.m @@ -9,6 +9,8 @@ #import "SVGSVGElement.h" #import "SVGGradientLayer.h" +#import "SVGKDefine_Private.h" + @implementation SVGHelperUtilities diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGLength.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGLength.m index cc336995a..c67a7ca5b 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGLength.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGLength.m @@ -4,6 +4,7 @@ #import "CSSPrimitiveValue_ConfigurablePixelsPerInch.h" #import "SVGUtils.h" +#import "SVGKDefine_Private.h" #include <sys/types.h> #include <sys/sysctl.h> diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGRect.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGRect.m index 9525d1e4f..cff0073de 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGRect.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/SVG-DOM/SVGRect.m @@ -1,4 +1,5 @@ #import "SVGRect.h" +#import "SVGKDefine_Private.h" BOOL SVGRectIsInitialized( SVGRect rect ) { diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGCircleElement.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGCircleElement.m index 855c5613e..0dc06ace9 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGCircleElement.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGCircleElement.m @@ -6,6 +6,7 @@ // #import "SVGCircleElement.h" +#import "SVGKDefine_Private.h" @implementation SVGCircleElement diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGElement.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGElement.m index 2b22c54cb..4164e7246 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGElement.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGElement.m @@ -20,6 +20,8 @@ #import "SVGTransformable.h" +#import "SVGKDefine_Private.h" + @interface SVGElement () @property (nonatomic, copy) NSString *stringValue; diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGGradientElement.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGGradientElement.m index 481ee4f36..8e8aa61f7 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGGradientElement.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGGradientElement.m @@ -5,6 +5,7 @@ #import "SVGGElement.h" #import "SVGLinearGradientElement.h" #import "SVGRadialGradientElement.h" +#import "SVGKDefine_Private.h" @implementation SVGGradientElement diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGImageElement.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGImageElement.m index e929967ab..99704ec87 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGImageElement.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGImageElement.m @@ -9,6 +9,8 @@ #import "SVGKSourceNSData.h" #import "SVGKInlineResource.h" +#import "SVGKDefine_Private.h" + CGImageRef SVGImageCGImage(UIImage *img) { #if SVGKIT_UIKIT diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGLinearGradientElement.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGLinearGradientElement.m index 8bc83e38e..d3ac80b59 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGLinearGradientElement.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGLinearGradientElement.m @@ -9,6 +9,7 @@ #import "SVGLinearGradientElement.h" #import "SVGElement_ForParser.h" #import "SVGGradientLayer.h" +#import "SVGKDefine_Private.h" @interface SVGLinearGradientElement () diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGPathElement.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGPathElement.m index 823d17835..35d9607e0 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGPathElement.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGPathElement.m @@ -12,6 +12,8 @@ #import "SVGElement_ForParser.h" // to resolve Xcode circular dependencies; in long term, parsing SHOULD NOT HAPPEN inside any class whose name starts "SVG" (because those are reserved classes for the SVG Spec) +#import "SVGKDefine_Private.h" + @interface SVGPathElement () - (void) parseData:(NSString *)data; diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGRadialGradientElement.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGRadialGradientElement.m index a0867512c..2138d168a 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGRadialGradientElement.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGRadialGradientElement.m @@ -10,6 +10,7 @@ #import "SVGElement_ForParser.h" #import "SVGUtils.h" #import "SVGGradientLayer.h" +#import "SVGKDefine_Private.h" // `kCAGradientLayerRadial` this symbol is available since iOS 3.2/tvOS 9.0/macOS 10.6, but it's not externed to public header until Xcode 10 with iOS 12 SDK, so we define it for user who still use old SDK version. #define kCAGradientLayerRadial @"radial" diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGSVGElement.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGSVGElement.m index 00fa693d3..8137481c8 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGSVGElement.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGSVGElement.m @@ -7,6 +7,8 @@ #import "SVGElement_ForParser.h" // to resolve Xcode circular dependencies; in long term, parsing SHOULD NOT HAPPEN inside any class whose name starts "SVG" (because those are reserved classes for the SVG Spec) +#import "SVGKDefine_Private.h" + @interface SVGSVGElement() #pragma mark - elements REQUIRED to implement the spec but not included in SVG Spec due to bugs in the spec writing! @property(nonatomic,readwrite) SVGRect requestedViewport; diff --git a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGTextElement.m b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGTextElement.m index 0ac9dd525..f425e0f36 100644 --- a/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGTextElement.m +++ b/Carthage/Checkouts/SVGKit/Source/DOM classes/Unported or Partial DOM/SVGTextElement.m @@ -6,6 +6,7 @@ #import "SVGHelperUtilities.h" #import "SVGUtils.h" #import "SVGTextLayer.h" +#import "SVGKDefine_Private.h" @implementation SVGTextElement diff --git a/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterNSImage.h b/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterNSImage.h index 5e6eecb45..42251d3a1 100644 --- a/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterNSImage.h +++ b/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterNSImage.h @@ -3,6 +3,10 @@ Uses the default color format from UIGraphicsBeginImageContextWithOptions(...) */ + +#import "SVGKDefine.h" + +#if SVGKIT_MAC #import <Foundation/Foundation.h> #import "SVGKImage.h" @@ -29,3 +33,5 @@ +(NSImage*) exportAsNSImage:(SVGKImage*) image antiAliased:(BOOL) shouldAntialias curveFlatnessFactor:(CGFloat) multiplyFlatness interpolationQuality:(CGInterpolationQuality) interpolationQuality; @end + +#endif /* SVGKIT_MAC */ diff --git a/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterNSImage.m b/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterNSImage.m index f8340a483..ccb5cfaf0 100644 --- a/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterNSImage.m +++ b/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterNSImage.m @@ -1,7 +1,10 @@ #import "SVGKExporterNSImage.h" + +#if SVGKIT_MAC #import "SVGUtils.h" #import "SVGKImage+CGContext.h" // needed for Context calls #import <objc/runtime.h> +#import "SVGKDefine_Private.h" @implementation SVGKExporterNSImage @@ -133,3 +136,5 @@ static NSImage * SVGKGraphicsGetImageFromCurrentImageContext(void) { } @end + +#endif /* SVGKIT_MAC */ diff --git a/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterUIImage.m b/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterUIImage.m index d218e0f0a..0f0b66e89 100644 --- a/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterUIImage.m +++ b/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKExporterUIImage.m @@ -1,5 +1,7 @@ #import "SVGKExporterUIImage.h" +#import "SVGKDefine_Private.h" +#if SVGKIT_UIKIT #import "SVGKImage+CGContext.h" // needed for Context calls @implementation SVGKExporterUIImage @@ -35,3 +37,5 @@ } @end + +#endif /* SVGKIT_UIKIT */ diff --git a/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKImage+CGContext.m b/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKImage+CGContext.m index 7e402f4f0..88cc7ffa0 100644 --- a/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKImage+CGContext.m +++ b/Carthage/Checkouts/SVGKit/Source/Exporters/SVGKImage+CGContext.m @@ -11,6 +11,8 @@ #import "SVGRect.h" #import "SVGSVGElement.h" +#import "SVGKDefine_Private.h" + @implementation SVGKImage (CGContext) -(CGContextRef) newCGContextAutosizedToFit diff --git a/Carthage/Checkouts/SVGKit/Source/Foundation additions/NSCharacterSet+SVGKExtensions.m b/Carthage/Checkouts/SVGKit/Source/Foundation additions/NSCharacterSet+SVGKExtensions.m index 842880963..d35622c86 100644 --- a/Carthage/Checkouts/SVGKit/Source/Foundation additions/NSCharacterSet+SVGKExtensions.m +++ b/Carthage/Checkouts/SVGKit/Source/Foundation additions/NSCharacterSet+SVGKExtensions.m @@ -7,6 +7,7 @@ // #import "NSCharacterSet+SVGKExtensions.h" +#import "SVGKDefine_Private.h" @implementation NSCharacterSet (SVGKExtensions) diff --git a/Carthage/Checkouts/SVGKit/Source/Foundation additions/NSData+NSInputStream.m b/Carthage/Checkouts/SVGKit/Source/Foundation additions/NSData+NSInputStream.m index 967ec98e7..25d73c009 100644 --- a/Carthage/Checkouts/SVGKit/Source/Foundation additions/NSData+NSInputStream.m +++ b/Carthage/Checkouts/SVGKit/Source/Foundation additions/NSData+NSInputStream.m @@ -7,7 +7,7 @@ // #import "NSData+NSInputStream.h" - +#import "SVGKDefine_Private.h" #define BUFSIZE 65536U diff --git a/Carthage/Checkouts/SVGKit/Source/Parsers/Parser Extensions/SVGKParserSVG.m b/Carthage/Checkouts/SVGKit/Source/Parsers/Parser Extensions/SVGKParserSVG.m index 172653ffe..4b1ae5fe7 100644 --- a/Carthage/Checkouts/SVGKit/Source/Parsers/Parser Extensions/SVGKParserSVG.m +++ b/Carthage/Checkouts/SVGKit/Source/Parsers/Parser Extensions/SVGKParserSVG.m @@ -21,6 +21,8 @@ #import "SVGDocument_Mutable.h" +#import "SVGKDefine_Private.h" + @interface SVGKParserSVG () @property (nonatomic) NSArray *supportedNamespaces; @property (nonatomic) NSDictionary *elementMap; diff --git a/Carthage/Checkouts/SVGKit/Source/Parsers/SVGKParseResult.m b/Carthage/Checkouts/SVGKit/Source/Parsers/SVGKParseResult.m index 7d85e73bc..26ddc0838 100644 --- a/Carthage/Checkouts/SVGKit/Source/Parsers/SVGKParseResult.m +++ b/Carthage/Checkouts/SVGKit/Source/Parsers/SVGKParseResult.m @@ -1,4 +1,5 @@ #import "SVGKParseResult.h" +#import "SVGKDefine_Private.h" @implementation SVGKParseResult diff --git a/Carthage/Checkouts/SVGKit/Source/Parsers/SVGKParser.m b/Carthage/Checkouts/SVGKit/Source/Parsers/SVGKParser.m index edf62daac..521c2beb5 100644 --- a/Carthage/Checkouts/SVGKit/Source/Parsers/SVGKParser.m +++ b/Carthage/Checkouts/SVGKit/Source/Parsers/SVGKParser.m @@ -31,6 +31,8 @@ #import "StyleSheetList+Mutable.h" #import "NSData+NSInputStream.h" +#import "SVGKDefine_Private.h" + @interface SVGKParser() @property(nonatomic,strong, readwrite) SVGKSource* source; @property(nonatomic,strong, readwrite) NSMutableArray* externalStylesheets; diff --git a/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CALayerWithClipRender.m b/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CALayerWithClipRender.m index daeec18f1..8b64781da 100644 --- a/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CALayerWithClipRender.m +++ b/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CALayerWithClipRender.m @@ -7,6 +7,11 @@ // #import "CALayerWithClipRender.h" +#import "SVGKDefine.h" + +#if SVGKIT_UIKIT +#import <UIKit/UIKit.h> +#endif @interface CALayer (ContentsTransform) diff --git a/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CAShapeLayerWithHitTest.m b/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CAShapeLayerWithHitTest.m index 6c24acc11..f0b7379d1 100644 --- a/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CAShapeLayerWithHitTest.m +++ b/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CAShapeLayerWithHitTest.m @@ -1,4 +1,5 @@ #import "CAShapeLayerWithHitTest.h" +#import "SVGKDefine_Private.h" /*! Used by the main ShapeElement (and all subclasses) to do perfect "containsPoint" calculations via Apple's API calls diff --git a/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CGPathAdditions.m b/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CGPathAdditions.m index 968d2b211..c7720a2ae 100644 --- a/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CGPathAdditions.m +++ b/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/CGPathAdditions.m @@ -6,6 +6,7 @@ // #import "CGPathAdditions.h" +#import <stdlib.h> void applier (void *info, const CGPathElement *element); diff --git a/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/SVGGradientLayer.m b/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/SVGGradientLayer.m index 6dbd4199d..f87db0506 100644 --- a/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/SVGGradientLayer.m +++ b/Carthage/Checkouts/SVGKit/Source/QuartzCore additions/SVGGradientLayer.m @@ -10,6 +10,7 @@ #import "SVGRadialGradientElement.h" #import "SVGLinearGradientElement.h" #import "CALayerWithClipRender.h" +#import "SVGKDefine_Private.h" @implementation SVGGradientLayer diff --git a/Carthage/Checkouts/SVGKit/Source/SVGKImage.m b/Carthage/Checkouts/SVGKit/Source/SVGKImage.m index 630314343..897681abd 100644 --- a/Carthage/Checkouts/SVGKit/Source/SVGKImage.m +++ b/Carthage/Checkouts/SVGKit/Source/SVGKImage.m @@ -25,6 +25,8 @@ #import "SVGKExporterUIImage.h" // needed for .UIImage property #endif +#import "SVGKDefine_Private.h" + #if ENABLE_GLOBAL_IMAGE_CACHE_FOR_SVGKIMAGE_IMAGE_NAMED @interface SVGKImageCacheLine : NSObject @property(nonatomic) int numberOfInstances; diff --git a/Carthage/Checkouts/SVGKit/Source/SVGKit.h b/Carthage/Checkouts/SVGKit/Source/SVGKit.h index 32c911127..b25b965ba 100644 --- a/Carthage/Checkouts/SVGKit/Source/SVGKit.h +++ b/Carthage/Checkouts/SVGKit/Source/SVGKit.h @@ -163,9 +163,11 @@ FOUNDATION_EXPORT const unsigned char SVGKitFramework_VersionString[]; #import "SVGKImage.h" #import "SVGKSource.h" #import "NSCharacterSet+SVGKExtensions.h" +#if SVGKIT_UIKIT #import "SVGKFastImageView.h" #import "SVGKImageView.h" #import "SVGKLayeredImageView.h" +#endif #import "SVGKPattern.h" #import "SVGUtils.h" #if SVGKIT_MAC diff --git a/Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceLocalFile.m b/Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceLocalFile.m index 03afd5d0b..956f1cdd2 100644 --- a/Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceLocalFile.m +++ b/Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceLocalFile.m @@ -1,4 +1,5 @@ #import "SVGKSourceLocalFile.h" +#import "SVGKDefine_Private.h" @interface SVGKSourceLocalFile() @property (nonatomic, readwrite) BOOL wasRelative; diff --git a/Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceNSData.m b/Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceNSData.m index e407e7cec..0d81a8f3a 100644 --- a/Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceNSData.m +++ b/Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceNSData.m @@ -1,6 +1,7 @@ #import "SVGKSourceNSData.h" #import "SVGKSourceURL.h" // used for delegating when asked to construct relative links +#import "SVGKDefine_Private.h" @implementation SVGKSourceNSData diff --git a/Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceURL.m b/Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceURL.m index e8fef7c16..0437ba178 100644 --- a/Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceURL.m +++ b/Carthage/Checkouts/SVGKit/Source/Sources/SVGKSourceURL.m @@ -1,4 +1,5 @@ #import "SVGKSourceURL.h" +#import "SVGKDefine_Private.h" @implementation SVGKSourceURL diff --git a/Carthage/Checkouts/SVGKit/Source/UIKit additions/SVGKFastImageView.m b/Carthage/Checkouts/SVGKit/Source/UIKit additions/SVGKFastImageView.m index 6cac8e592..d8d66f324 100644 --- a/Carthage/Checkouts/SVGKit/Source/UIKit additions/SVGKFastImageView.m +++ b/Carthage/Checkouts/SVGKit/Source/UIKit additions/SVGKFastImageView.m @@ -1,4 +1,5 @@ #import "SVGKFastImageView.h" +#import "SVGKDefine_Private.h" @interface SVGKFastImageView () @property(nonatomic,readwrite) NSTimeInterval timeIntervalForLastReRenderOfSVGFromMemory; diff --git a/Carthage/Checkouts/SVGKit/Source/UIKit additions/SVGKLayeredImageView.m b/Carthage/Checkouts/SVGKit/Source/UIKit additions/SVGKLayeredImageView.m index 571bb3974..062cf82cf 100644 --- a/Carthage/Checkouts/SVGKit/Source/UIKit additions/SVGKLayeredImageView.m +++ b/Carthage/Checkouts/SVGKit/Source/UIKit additions/SVGKLayeredImageView.m @@ -5,6 +5,8 @@ #import "SVGKSourceString.h" #import "SVGKInlineResource.h" +#import "SVGKDefine_Private.h" + @interface SVGKLayeredImageView() @property(nonatomic,strong) CAShapeLayer* internalBorderLayer; @end diff --git a/Carthage/Checkouts/SVGKit/Source/Utils/SVGUtils.h b/Carthage/Checkouts/SVGKit/Source/Utils/SVGUtils.h index 092651f51..01d5f7136 100644 --- a/Carthage/Checkouts/SVGKit/Source/Utils/SVGUtils.h +++ b/Carthage/Checkouts/SVGKit/Source/Utils/SVGUtils.h @@ -5,6 +5,7 @@ // Copyright Matt Rajca 2010-2011. All rights reserved. // +#import <Foundation/Foundation.h> #import <CoreFoundation/CoreFoundation.h> #import <CoreGraphics/CoreGraphics.h> diff --git a/Carthage/Checkouts/SVGKit/Source/Utils/SVGUtils.m b/Carthage/Checkouts/SVGKit/Source/Utils/SVGUtils.m index 6166ab805..48ef3a3c9 100644 --- a/Carthage/Checkouts/SVGKit/Source/Utils/SVGUtils.m +++ b/Carthage/Checkouts/SVGKit/Source/Utils/SVGUtils.m @@ -6,6 +6,7 @@ // #import "SVGUtils.h" +#import "SVGKDefine_Private.h" #define MAX_ACCUM 64 #define NUM_COLORS 148 diff --git a/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/Base.lproj/Main.storyboard b/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/Base.lproj/Main.storyboard index b0eef3525..df2e036e6 100644 --- a/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/Base.lproj/Main.storyboard +++ b/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/Base.lproj/Main.storyboard @@ -1,11 +1,9 @@ <?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" useSafeAreas="YES" colorMatched="YES" initialViewController="vXZ-lx-hvc"> - <device id="retina4_7" orientation="portrait"> - <adaptation id="fullscreen"/> - </device> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="vXZ-lx-hvc"> + <device id="retina4_7" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> @@ -19,7 +17,7 @@ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <subviews> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="50" translatesAutoresizingMaskIntoConstraints="NO" id="3bJ-bG-tue"> - <rect key="frame" x="73" y="144" width="229" height="380"/> + <rect key="frame" x="73" y="57.5" width="229" height="552"/> <subviews> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zpy-9h-CPz"> <rect key="frame" x="0.0" y="0.0" width="229" height="36"/> @@ -29,16 +27,25 @@ <action selector="pickerButtonTap" destination="vXZ-lx-hvc" eventType="touchUpInside" id="0Q7-5M-ogn"/> </connections> </button> - <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="d6U-qB-bWX"> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="WKj-AD-9tA"> <rect key="frame" x="0.0" y="86" width="229" height="36"/> <fontDescription key="fontDescription" type="system" pointSize="20"/> + <state key="normal" title="Only Video Recording"/> + <connections> + <action selector="onlyVideoRecording:" destination="vXZ-lx-hvc" eventType="touchUpInside" id="GbK-VR-G0G"/> + <action selector="pickerButtonTap" destination="vXZ-lx-hvc" eventType="touchUpInside" id="zYL-bG-qij"/> + </connections> + </button> + <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="d6U-qB-bWX"> + <rect key="frame" x="0.0" y="172" width="229" height="36"/> + <fontDescription key="fontDescription" type="system" pointSize="20"/> <state key="normal" title="Custom CameraCell (Live)"/> <connections> <action selector="pickerWithCustomCameraCell" destination="vXZ-lx-hvc" eventType="touchUpInside" id="fXi-av-gMq"/> </connections> </button> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9kt-E5-QsD"> - <rect key="frame" x="0.0" y="172" width="229" height="36"/> + <rect key="frame" x="0.0" y="258" width="229" height="36"/> <fontDescription key="fontDescription" type="system" pointSize="20"/> <state key="normal" title="Custom BlackStyle"/> <connections> @@ -46,7 +53,7 @@ </connections> </button> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="icR-mj-SY4"> - <rect key="frame" x="0.0" y="258" width="229" height="36"/> + <rect key="frame" x="0.0" y="344" width="229" height="36"/> <fontDescription key="fontDescription" type="system" pointSize="20"/> <state key="normal" title="with NavigationController"> <color key="titleColor" red="0.1019607843" green="0.73725490199999999" blue="0.61176470589999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> @@ -56,7 +63,7 @@ </connections> </button> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VP9-SK-f4B"> - <rect key="frame" x="0.0" y="344" width="229" height="36"/> + <rect key="frame" x="0.0" y="430" width="229" height="36"/> <fontDescription key="fontDescription" type="system" pointSize="20"/> <state key="normal" title="with custom rules"> <color key="titleColor" red="0.27450980390000002" green="0.31372549020000001" blue="0.37647058820000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> @@ -66,7 +73,7 @@ </connections> </button> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="W1Y-V8-qUq"> - <rect key="frame" x="0.0" y="344" width="229" height="36"/> + <rect key="frame" x="0.0" y="516" width="229" height="36"/> <fontDescription key="fontDescription" type="system" pointSize="20"/> <state key="normal" title="with Custom Layout"/> <connections> @@ -76,7 +83,7 @@ </subviews> </stackView> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="u8O-io-kHd"> - <rect key="frame" x="137.5" y="534" width="100" height="112"/> + <rect key="frame" x="137.5" y="619.5" width="100" height="112"/> <subviews> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="get image message" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9CM-MS-96X"> <rect key="frame" x="3" y="0.0" width="94" height="12"/> diff --git a/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/ViewController.swift b/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/ViewController.swift index a1bb569e2..b6f7cd9df 100644 --- a/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/ViewController.swift +++ b/Carthage/Checkouts/TLPhotoPicker/Example/TLPhotoPicker/ViewController.swift @@ -31,6 +31,24 @@ class ViewController: UIViewController,TLPhotosPickerViewControllerDelegate { self.present(viewController, animated: true, completion: nil) } + @IBAction func onlyVideoRecording(_ sender: Any) { + let viewController = CustomPhotoPickerViewController() + viewController.delegate = self + viewController.didExceedMaximumNumberOfSelection = { [weak self] (picker) in + self?.showExceededMaximumAlert(vc: picker) + } + var configure = TLPhotosPickerConfigure() + configure.numberOfColumn = 3 + configure.allowedPhotograph = false + configure.allowedVideoRecording = true + configure.mediaType = .video + viewController.configure = configure + viewController.selectedAssets = self.selectedAssets + viewController.logDelegate = self + + self.present(viewController, animated: true, completion: nil) + } + @IBAction func pickerWithCustomCameraCell() { let viewController = CustomPhotoPickerViewController() viewController.delegate = self diff --git a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift b/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift index 5d043f075..76bc65799 100644 --- a/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift +++ b/Carthage/Checkouts/TLPhotoPicker/TLPhotoPicker/Classes/TLPhotosPickerViewController.swift @@ -67,6 +67,7 @@ public struct TLPhotosPickerConfigure { public var allowedLivePhotos = true public var allowedVideo = true public var allowedAlbumCloudShared = false + public var allowedPhotograph = true public var allowedVideoRecording = true public var recordingVideoQuality: UIImagePickerController.QualityType = .typeMedium public var maxVideoDuration:TimeInterval? = nil @@ -598,14 +599,21 @@ extension TLPhotosPickerViewController: UIImagePickerControllerDelegate, UINavig guard !maxCheck() else { return } let picker = UIImagePickerController() picker.sourceType = .camera - picker.mediaTypes = [kUTTypeImage as String] + var mediaTypes: [String] = [] + if self.configure.allowedPhotograph { + mediaTypes.append(kUTTypeImage as String) + } if self.configure.allowedVideoRecording { - picker.mediaTypes.append(kUTTypeMovie as String) + mediaTypes.append(kUTTypeMovie as String) picker.videoQuality = self.configure.recordingVideoQuality if let duration = self.configure.maxVideoDuration { picker.videoMaximumDuration = duration } } + guard mediaTypes.count > 0 else { + return + } + picker.mediaTypes = mediaTypes picker.allowsEditing = false picker.delegate = self self.present(picker, animated: true, completion: nil) @@ -632,6 +640,7 @@ extension TLPhotosPickerViewController: UIImagePickerControllerDelegate, UINavig let newAssetRequest = PHAssetChangeRequest.creationRequestForAsset(from: image) placeholderAsset = newAssetRequest.placeholderForCreatedAsset }, completionHandler: { [weak self] (success, error) in + guard self?.maxCheck() == false else { return } if success, let `self` = self, let identifier = placeholderAsset?.localIdentifier { guard let asset = PHAsset.fetchAssets(withLocalIdentifiers: [identifier], options: nil).firstObject else { return } var result = TLPHAsset(asset: asset) @@ -648,6 +657,7 @@ extension TLPhotosPickerViewController: UIImagePickerControllerDelegate, UINavig let newAssetRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: info[.mediaURL] as! URL) placeholderAsset = newAssetRequest?.placeholderForCreatedAsset }) { [weak self] (sucess, error) in + guard self?.maxCheck() == false else { return } if sucess, let `self` = self, let identifier = placeholderAsset?.localIdentifier { guard let asset = PHAsset.fetchAssets(withLocalIdentifiers: [identifier], options: nil).firstObject else { return } var result = TLPHAsset(asset: asset) diff --git a/Carthage/Checkouts/realm-cocoa/.gitignore b/Carthage/Checkouts/realm-cocoa/.gitignore index 158877276..f460e8092 100644 --- a/Carthage/Checkouts/realm-cocoa/.gitignore +++ b/Carthage/Checkouts/realm-cocoa/.gitignore @@ -117,3 +117,5 @@ Realm/ObjectServerTests/node_modules .swiftpm .build Package.resolved + +examples/installation/ios/swift/SwiftPackageManagerExample/SwiftPackageManagerExample.xcodeproj diff --git a/Carthage/Checkouts/realm-cocoa/.jenkins.yml b/Carthage/Checkouts/realm-cocoa/.jenkins.yml index df5a470b9..192222ec9 100644 --- a/Carthage/Checkouts/realm-cocoa/.jenkins.yml +++ b/Carthage/Checkouts/realm-cocoa/.jenkins.yml @@ -7,6 +7,7 @@ xcode_version: - 11.3 - 11.4.1 - 11.5 + - 11.6 - 12.0 target: - docs @@ -62,6 +63,14 @@ exclude: target: docs configuration: Release + - xcode_version: 11.6 + target: docs + configuration: Debug + + - xcode_version: 11.6 + target: docs + configuration: Release + - xcode_version: 12.0 target: docs configuration: Debug @@ -90,6 +99,14 @@ exclude: target: swiftlint configuration: Release + - xcode_version: 11.6 + target: swiftlint + configuration: Debug + + - xcode_version: 11.6 + target: swiftlint + configuration: Release + - xcode_version: 12.0 target: swiftlint configuration: Debug @@ -114,6 +131,14 @@ exclude: target: osx-encryption configuration: Release + - xcode_version: 11.6 + target: osx-encryption + configuration: Debug + + - xcode_version: 11.6 + target: osx-encryption + configuration: Release + - xcode_version: 12.0 target: osx-encryption configuration: Debug @@ -138,6 +163,14 @@ exclude: target: osx-object-server configuration: Release + - xcode_version: 11.6 + target: osx-object-server + configuration: Debug + + - xcode_version: 11.6 + target: osx-object-server + configuration: Release + - xcode_version: 12.0 target: osx-object-server configuration: Debug @@ -162,6 +195,14 @@ exclude: target: ios-static configuration: Release + - xcode_version: 11.6 + target: ios-static + configuration: Debug + + - xcode_version: 11.6 + target: ios-static + configuration: Release + - xcode_version: 12.0 target: ios-static configuration: Debug @@ -186,6 +227,14 @@ exclude: target: ios-dynamic configuration: Release + - xcode_version: 11.6 + target: ios-dynamic + configuration: Debug + + - xcode_version: 11.6 + target: ios-dynamic + configuration: Release + - xcode_version: 12.0 target: ios-dynamic configuration: Debug @@ -210,6 +259,14 @@ exclude: target: watchos configuration: Release + - xcode_version: 11.6 + target: watchos + configuration: Debug + + - xcode_version: 11.6 + target: watchos + configuration: Release + - xcode_version: 12.0 target: watchos configuration: Debug @@ -234,6 +291,14 @@ exclude: target: tvos configuration: Release + - xcode_version: 11.6 + target: tvos + configuration: Debug + + - xcode_version: 11.6 + target: tvos + configuration: Release + - xcode_version: 12.0 target: tvos configuration: Debug @@ -258,6 +323,14 @@ exclude: target: ios-swift configuration: Release + - xcode_version: 11.6 + target: ios-swift + configuration: Debug + + - xcode_version: 11.6 + target: ios-swift + configuration: Release + - xcode_version: 12.0 target: ios-swift configuration: Debug @@ -282,6 +355,14 @@ exclude: target: tvos-swift configuration: Release + - xcode_version: 11.6 + target: tvos-swift + configuration: Debug + + - xcode_version: 11.6 + target: tvos-swift + configuration: Release + - xcode_version: 12.0 target: tvos-swift configuration: Debug @@ -306,6 +387,14 @@ exclude: target: catalyst configuration: Release + - xcode_version: 11.6 + target: catalyst + configuration: Debug + + - xcode_version: 11.6 + target: catalyst + configuration: Release + - xcode_version: 12.0 target: catalyst configuration: Debug @@ -330,6 +419,14 @@ exclude: target: catalyst-swift configuration: Release + - xcode_version: 11.6 + target: catalyst-swift + configuration: Debug + + - xcode_version: 11.6 + target: catalyst-swift + configuration: Release + - xcode_version: 12.0 target: catalyst-swift configuration: Debug @@ -358,6 +455,14 @@ exclude: target: xcframework configuration: Release + - xcode_version: 11.6 + target: xcframework + configuration: Debug + + - xcode_version: 11.6 + target: xcframework + configuration: Release + - xcode_version: 12.0 target: xcframework configuration: Debug @@ -374,6 +479,10 @@ exclude: target: cocoapods-osx configuration: Debug + - xcode_version: 11.6 + target: cocoapods-osx + configuration: Debug + - xcode_version: 12.0 target: cocoapods-osx configuration: Debug @@ -398,6 +507,14 @@ exclude: target: cocoapods-ios configuration: Release + - xcode_version: 11.6 + target: cocoapods-ios + configuration: Debug + + - xcode_version: 11.6 + target: cocoapods-ios + configuration: Release + - xcode_version: 12.0 target: cocoapods-ios configuration: Debug @@ -422,6 +539,14 @@ exclude: target: cocoapods-ios-dynamic configuration: Release + - xcode_version: 11.6 + target: cocoapods-ios-dynamic + configuration: Debug + + - xcode_version: 11.6 + target: cocoapods-ios-dynamic + configuration: Release + - xcode_version: 12.0 target: cocoapods-ios-dynamic configuration: Debug @@ -446,6 +571,14 @@ exclude: target: cocoapods-watchos configuration: Release + - xcode_version: 11.6 + target: cocoapods-watchos + configuration: Debug + + - xcode_version: 11.6 + target: cocoapods-watchos + configuration: Release + - xcode_version: 12.0 target: cocoapods-watchos configuration: Debug @@ -470,6 +603,14 @@ exclude: target: swiftpm configuration: Release + - xcode_version: 11.6 + target: swiftpm + configuration: Debug + + - xcode_version: 11.6 + target: swiftpm + configuration: Release + - xcode_version: 12.0 target: swiftpm configuration: Debug @@ -498,6 +639,14 @@ exclude: target: swiftpm-address configuration: Release + - xcode_version: 11.6 + target: swiftpm-address + configuration: Debug + + - xcode_version: 11.6 + target: swiftpm-address + configuration: Release + - xcode_version: 12.0 target: swiftpm-address configuration: Debug @@ -526,6 +675,14 @@ exclude: target: swiftpm-thread configuration: Release + - xcode_version: 11.6 + target: swiftpm-thread + configuration: Debug + + - xcode_version: 11.6 + target: swiftpm-thread + configuration: Release + - xcode_version: 12.0 target: swiftpm-thread configuration: Debug @@ -554,6 +711,14 @@ exclude: target: swiftpm-ios configuration: Release + - xcode_version: 11.6 + target: swiftpm-ios + configuration: Debug + + - xcode_version: 11.6 + target: swiftpm-ios + configuration: Release + - xcode_version: 12.0 target: swiftpm-ios configuration: Debug diff --git a/Carthage/Checkouts/realm-cocoa/.travis.yml b/Carthage/Checkouts/realm-cocoa/.travis.yml index b9f2ee418..99c5f1b53 100644 --- a/Carthage/Checkouts/realm-cocoa/.travis.yml +++ b/Carthage/Checkouts/realm-cocoa/.travis.yml @@ -1,5 +1,5 @@ language: objective-c -osx_image: xcode10.2 +osx_image: xcode11.6 branches: only: master script: placeholder # workaround for https://github.com/travis-ci/travis-ci/issues/4681 diff --git a/Carthage/Checkouts/realm-cocoa/CHANGELOG.md b/Carthage/Checkouts/realm-cocoa/CHANGELOG.md index 8264dd7bf..095f30b4a 100644 --- a/Carthage/Checkouts/realm-cocoa/CHANGELOG.md +++ b/Carthage/Checkouts/realm-cocoa/CHANGELOG.md @@ -1,3 +1,101 @@ +5.3.2 Release notes (2020-07-21) +============================================================= + +### Fixed + +* Fix a file format upgrade bug when opening older Realm files.. Could cause + assertions like "Assertion failed: ref != 0" during opning of a Realm. + ([Core #6644](https://github.com/realm/realm-cocoa/issues/6644), since 5.2.0) +* A use-after-free would occur if a Realm was compacted, opened on multiple + threads prior to the first write, then written to while reads were happening + on other threads. This could result in a variety of crashes, often inside + realm::util::EncryptedFileMapping::read_barrier. + (Since v5.0.0, [#6626](https://github.com/realm/realm-cocoa/issues/6626), + [#6628](https://github.com/realm/realm-cocoa/issues/6628), + [#6652](https://github.com/realm/realm-cocoa/issues/6652), + [#6655](https://github.com/realm/realm-cocoa/issues/6555), + [#6656](https://github.com/realm/realm-cocoa/issues/6656)). + +### Compatibility + +* File format: Generates Realms with format v10 (Reads and upgrades all previous formats) +* Realm Object Server: 3.21.0 or later. +* Realm Studio: 3.11 or later. +* APIs are backwards compatible with all previous releases in the 5.x.y series. +* Carthage release for Swift is built with Xcode 11.6. + +### Internal + +* Upgraded realm-core from v6.0.11 to v6.0.12 +* Upgraded realm-sync from v5.0.11 to v5.0.12 + +5.3.1 Release notes (2020-07-17) +============================================================= + +### Enhancements + +* Add prebuilt binary for Xcode 11.6 to the release package. + +### Fixed + +* Creating an object inside migration which changed that object type's primary + key would hit an assertion failure mentioning primary_key_col + ([#6613](https://github.com/realm/realm-cocoa/issues/6613), since 5.0.0). +* Modifying the value of a string primary key property inside a migration with + a Realm file which was upgraded from pre-5.0 would corrupt the property's + index, typically resulting in crashes. ([Core #3765](https://github.com/realm/realm-core/issues/3765), since 5.0.0). +* Some Realm files which hit assertion failures when upgrading from the pre-5.0 + file format should now upgrade correctly (Since 5.0.0). + +### Compatibility + +* File format: Generates Realms with format v10 (Reads and upgrades all previous formats) +* Realm Object Server: 3.21.0 or later. +* Realm Studio: 3.11 or later. +* APIs are backwards compatible with all previous releases in the 5.x.y series. +* Carthage release for Swift is built with Xcode 11.6. + +### Internal + +* Upgraded realm-core from v6.0.9 to v6.0.11 +* Upgraded realm-sync from v5.0.8 to v5.0.11 + +5.3.0 Release notes (2020-07-14) +============================================================= + +### Enhancements + +* Add `Realm.objectWillChange`, which is a Combine publisher that will emit a + notification each time the Realm is refreshed or a write transaction is + commited. + +### Fixed + +* Fix the spelling of `ObjectKeyIdentifiable`. The old spelling is available + and deprecated for compatiblity. +* Rename `RealmCollection.publisher` to `RealmCollection.collectionPublisher`. + The old name interacted with the `publisher` defined by `Sequence` in very + confusing ways, so we need to use a different name. The `publisher` name is + still available for compatiblity. ([#6516](https://github.com/realm/realm-cocoa/issues/6516)) +* Work around "xcodebuild timed out while trying to read + SwiftPackageManagerExample.xcodeproj" errors when installing Realm via + Carthage. ([#6549](https://github.com/realm/realm-cocoa/issues/6549)). +* Fix a performance regression when using change notifications. (Since 5.0.0, + [#6629](https://github.com/realm/realm-cocoa/issues/6629)). + +### Compatibility + +* File format: Generates Realms with format v10 (Reads and upgrades all previous formats) +* Realm Object Server: 3.21.0 or later. +* Realm Studio: 3.11 or later. +* APIs are backwards compatible with all previous releases in the 5.x.y series. +* Carthage release for Swift is built with Xcode 11.5. + +### Internal + +* Upgraded realm-core from v6.0.8 to v6.0.9 +* Upgraded realm-sync from v5.0.7 to v5.0.8 + 5.2.0 Release notes (2020-06-30) ============================================================= diff --git a/Carthage/Checkouts/realm-cocoa/Jenkinsfile.releasability b/Carthage/Checkouts/realm-cocoa/Jenkinsfile.releasability index cd77baf83..7e9aac3d4 100644 --- a/Carthage/Checkouts/realm-cocoa/Jenkinsfile.releasability +++ b/Carthage/Checkouts/realm-cocoa/Jenkinsfile.releasability @@ -1,4 +1,4 @@ -xcodeVersions = ['11.3', '11.4.1', '11.5'] +xcodeVersions = ['11.3', '11.4.1', '11.5', '11.6'] platforms = ['osx', 'ios', 'watchos', 'tvos', 'catalyst'] carthagePlatforms = ['osx', 'ios', 'watchos', 'tvos'] platformNames = ['osx': 'macOS', 'ios': 'iOS', 'watchos': 'watchOS', 'tvos': 'tvOS', 'catalyst': 'Catalyst'] diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list index 7f117e376..9710b0a6d 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list +++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/dependencies.list @@ -1,4 +1,4 @@ -REALM_CORE_VERSION=6.0.6 -REALM_SYNC_VERSION=5.0.5 +REALM_CORE_VERSION=6.0.10 +REALM_SYNC_VERSION=5.0.9 REALM_CORE_PACKAGING=2 OPENSSL_VERSION=1.1.1b diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.cpp b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.cpp index 11699290f..318da0c80 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.cpp +++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.cpp @@ -124,6 +124,23 @@ Property const& Object::property_for_name(StringData prop_name) const return *prop; } +void Object::validate_property_for_setter(Property const& property) const +{ + verify_attached(); + m_realm->verify_in_write(); + + // Modifying primary keys is allowed in migrations to make it possible to + // add a new primary key to a type (or change the property type), but it + // is otherwise considered the immutable identity of the row + if (property.is_primary) { + if (!m_realm->is_in_migration()) + throw ModifyPrimaryKeyException(m_object_schema->name, property.name); + // Modifying the PK property while it's the PK will corrupt the table, + // so remove it and then restore it at the end of the migration (which will rebuild the table) + m_obj.get_table()->set_primary_key_column({}); + } +} + #if REALM_ENABLE_SYNC void Object::ensure_user_in_everyone_role() { diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.hpp b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.hpp index 06cea3a1b..1f2751a2f 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.hpp +++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object.hpp @@ -146,6 +146,7 @@ private: void verify_attached() const; Property const& property_for_name(StringData prop_name) const; + void validate_property_for_setter(Property const&) const; }; struct InvalidatedObjectException : public std::logic_error { diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object_accessor.hpp b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object_accessor.hpp index c49897ff3..f02b6f901 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object_accessor.hpp +++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/object_accessor.hpp @@ -43,16 +43,8 @@ template <typename ValueType, typename ContextType> void Object::set_property_value(ContextType& ctx, StringData prop_name, ValueType value, CreatePolicy policy) { - verify_attached(); - m_realm->verify_in_write(); auto& property = property_for_name(prop_name); - - // Modifying primary keys is allowed in migrations to make it possible to - // add a new primary key to a type (or change the property type), but it - // is otherwise considered the immutable identity of the row - if (property.is_primary && !m_realm->is_in_migration()) - throw ModifyPrimaryKeyException(m_object_schema->name, property.name); - + validate_property_for_setter(property); set_property_value_impl(ctx, property, value, policy, false); } @@ -186,75 +178,91 @@ Object Object::create(ContextType& ctx, std::shared_ptr<Realm> const& realm, } template<typename ValueType, typename ContextType> +Mixed as_mixed(ContextType& ctx, ValueType& value, PropertyType type) +{ + if (!value) + return {}; + return switch_on_type(type, [&](auto* t) { + return Mixed(ctx.template unbox<NonObjTypeT<decltype(*t)>>(*value)); + }); +} + +template<typename ValueType, typename ContextType> Object Object::create(ContextType& ctx, std::shared_ptr<Realm> const& realm, ObjectSchema const& object_schema, ValueType value, CreatePolicy policy, ObjKey current_obj, Obj* out_row) { realm->verify_in_write(); - // get or create our accessor + // When setting each property, we normally want to skip over the primary key + // as that's set as part of object creation. However, during migrations the + // property marked as the primary key in the schema may not currently be + // considered a primary key by core, and so will need to be set. + bool skip_primary = true; + // If the input value is missing values for any of the properties we want to + // set the propery to the default value for new objects, but leave it + // untouched for existing objects. bool created = false; - // try to get existing row if updating Obj obj; auto table = realm->read_group().get_table(object_schema.table_key); - bool skip_primary = true; + // If there's a primary key, we need to first check if an object with the + // same primary key already exists. If it does, we either update that object + // or throw an exception if updating is disabled. if (auto primary_prop = object_schema.primary_key_property()) { - // search for existing object based on primary key type auto primary_value = ctx.value_for_property(value, *primary_prop, primary_prop - &object_schema.persisted_properties[0]); if (!primary_value) primary_value = ctx.default_value_for_property(object_schema, *primary_prop); - if (!primary_value) { - if (!is_nullable(primary_prop->type)) - throw MissingPropertyValueException(object_schema.name, primary_prop->name); - primary_value = ctx.null_value(); - } - auto key = get_for_primary_key_impl(ctx, *table, *primary_prop, *primary_value); - if (key) { - if (policy != CreatePolicy::ForceCreate) - obj = table->get_object(key); - else if (realm->is_in_migration()) { - // Creating objects with duplicate primary keys is allowed in migrations - // as long as there are no duplicates at the end, as adding an entirely - // new column which is the PK will inherently result in duplicates at first - obj = table->create_object(); - created = true; - skip_primary = false; - } - else { - throw std::logic_error(util::format("Attempting to create an object of type '%1' with an existing primary key value '%2'.", - object_schema.name, ctx.print(*primary_value))); + if (!primary_value && !is_nullable(primary_prop->type)) + throw MissingPropertyValueException(object_schema.name, primary_prop->name); + + // When changing the primary key of a table, we remove the existing pk (if any), call + // the migration function, then add the new pk (if any). This means that we can't call + // create_object_with_primary_key(), and creating duplicate primary keys is allowed as + // long as they're unique by the end of the migration. + if (table->get_primary_key_column() == ColKey{}) { + REALM_ASSERT(realm->is_in_migration()); + if (policy != CreatePolicy::ForceCreate) { + if (auto key = get_for_primary_key_impl(ctx, *table, *primary_prop, *primary_value)) + obj = table->get_object(key); } + if (!obj) + skip_primary = false; } else { - created = true; - Mixed primary_key; - if (primary_prop->type == PropertyType::Int) { - primary_key = ctx.template unbox<util::Optional<int64_t>>(*primary_value); - } - else if (primary_prop->type == PropertyType::String) { - primary_key = ctx.template unbox<StringData>(*primary_value); - } - else { - REALM_TERMINATE("Unsupported primary key type."); + obj = table->create_object_with_primary_key(as_mixed(ctx, primary_value, primary_prop->type), &created); + if (!created && policy == CreatePolicy::ForceCreate) { + if (!realm->is_in_migration()) { + throw std::logic_error(util::format("Attempting to create an object of type '%1' with an existing primary key value '%2'.", + object_schema.name, ctx.print(*primary_value))); + } + table->set_primary_key_column(ColKey{}); + skip_primary = false; + obj = {}; } - obj = table->create_object_with_primary_key(primary_key); } } - else { + + // No primary key (possibly temporarily due to migrations). If we're + // currently performing a recursive update on an existing object tree then + // an object key was passed in that we need to look up, and otherwise we + // need to create the new object. + if (!obj) { if (policy == CreatePolicy::UpdateModified && current_obj) { obj = table->get_object(current_obj); } else { - obj = table->create_object(); + obj = table->create_object(); created = true; } } - // populate Object object(realm, object_schema, obj); + // KVO in Cocoa requires that the obj ivar on the wrapper object be set + // *before* we start setting the properties, so it passes in a pointer to + // that. if (out_row) *out_row = obj; for (size_t i = 0; i < object_schema.persisted_properties.size(); ++i) { @@ -271,6 +279,9 @@ Object Object::create(ContextType& ctx, std::shared_ptr<Realm> const& realm, v = ctx.default_value_for_property(object_schema, prop); is_default = true; } + // We consider null or a missing value to be equivalent to an empty + // array for historical reasons; the original implementation did this + // accidentally and it's not worth changing. if ((!v || ctx.is_null(*v)) && !is_nullable(prop.type) && !is_array(prop.type)) { if (prop.is_primary || !ctx.allow_missing(value)) throw MissingPropertyValueException(object_schema.name, prop.name); diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/property.hpp b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/property.hpp index 9905c0b03..72198ae08 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/property.hpp +++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/property.hpp @@ -173,6 +173,19 @@ inline constexpr bool is_nullable(PropertyType a) return to_underlying(a & PropertyType::Nullable) == to_underlying(PropertyType::Nullable); } +// Some of the places we use switch_on_type() the Obj version isn't instantiatable +// or reachable, so we want to map it to a valid type to let the unreachable code compile +template<typename T> +struct NonObjType { + using type = std::remove_reference_t<T>; +}; +template<> +struct NonObjType<Obj&> { + using type = int64_t; +}; +template<typename T> +using NonObjTypeT = typename NonObjType<T>::type; + template<typename ObjType=Obj, typename Fn> static auto switch_on_type(PropertyType type, Fn&& fn) { diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/thread_safe_reference.cpp b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/thread_safe_reference.cpp index 80c6ec313..ecae494ae 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/thread_safe_reference.cpp +++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/src/thread_safe_reference.cpp @@ -109,19 +109,6 @@ private: std::string m_object_schema_name; }; -template<typename T> -struct ListType { - using type = Lst<std::remove_reference_t<T>>; -}; - -// The code path which would instantiate List<Obj> isn't reachable, but still -// produces errors about the type not being instantiable so we instead map it -// to an arbitrary valid type -template<> -struct ListType<Obj&> { - using type = Lst<int64_t>; -}; - template<> class ThreadSafeReference::PayloadImpl<Results> : public ThreadSafeReference::Payload { public: @@ -161,7 +148,7 @@ public: // match what happens for other types of handover where the // object doesn't exist. switch_on_type(ObjectSchema::from_core_type(*table, m_col_key), [&](auto* t) -> void { - list = std::make_unique<typename ListType<decltype(*t)>::type>(); + list = std::make_unique<Lst<NonObjTypeT<decltype(*t)>>>(); }); } return Results(r, std::move(list), m_ordering); diff --git a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/migrations.cpp b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/migrations.cpp index c944e4be5..5f4ca60b5 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/migrations.cpp +++ b/Carthage/Checkouts/realm-cocoa/Realm/ObjectStore/tests/migrations.cpp @@ -716,6 +716,14 @@ TEST_CASE("migration: Automatic") { {"array target", { {"value", PropertyType::Int}, }}, + {"int pk", { + {"pk", PropertyType::Int, Property::IsPrimary{true}}, + {"value", PropertyType::Int}, + }}, + {"string pk", { + {"pk", PropertyType::String, Property::IsPrimary{true}}, + {"value", PropertyType::Int}, + }}, }; InMemoryTestFile config; @@ -909,10 +917,22 @@ TEST_CASE("migration: Automatic") { }); } + SECTION("upsert in new realm after modifying primary key") { + realm->update_schema(schema, 2, [&values](auto, auto new_realm, Schema&) { + get_table(new_realm, "all types")->set_primary_key_column(ColKey()); + REQUIRE(new_realm->is_in_transaction()); + CppContext ctx(new_realm); + any_cast<AnyDict&>(values)["bool"] = false; + Object obj = Object::create(ctx, new_realm, "all types", values, CreatePolicy::UpdateAll); + REQUIRE(get_table(new_realm, "all types")->size() == 1); + REQUIRE(get_table(new_realm, "link target")->size() == 2); + REQUIRE(get_table(new_realm, "array target")->size() == 2); + REQUIRE(any_cast<bool>(obj.get_property_value<util::Any>(ctx, "bool")) == false); + }); + } + SECTION("change primary key property type") { schema = set_type(schema, "all types", "pk", PropertyType::String); - // FIXME: changing the primary key of a type with binary columns currently crashes in core - schema = remove_property(schema, "all types", "data"); realm->update_schema(schema, 2, [](auto, auto new_realm, auto&) { Object obj(new_realm, "all types", 0); @@ -943,6 +963,169 @@ TEST_CASE("migration: Automatic") { REQUIRE_NOTHROW(realm->update_schema(schema, 2, good_migration)); REQUIRE(get_table(realm, "all types")->size() == 2); } + + SECTION("modify existing int primary key values in migration") { + // Create several more objects to increase the chance of things + // actually breaking if we're doing invalid things + CppContext ctx(realm); + auto object_schema = realm->schema().find("all types"); + realm->begin_transaction(); + for (int i = 1; i < 10; ++i) { + any_cast<AnyDict&>(values)["pk"] = INT64_C(1) + i; + any_cast<AnyDict&>(values)["int"] = INT64_C(5) + i; + Object::create(ctx, realm, *object_schema, values); + } + realm->commit_transaction(); + + // Increase the PK of each object by one in a migration + realm->update_schema(schema, 2, [](auto, auto new_realm, Schema&) { + CppContext ctx(new_realm); + Results results(new_realm, get_table(new_realm, "all types")); + for (size_t i = 0, count = results.size(); i < count; ++i) { + Object obj(new_realm, results.get<Obj>(i)); + util::Any v = 1 + any_cast<int64_t>(obj.get_property_value<util::Any>(ctx, "pk")); + obj.set_property_value(ctx, "pk", v); + } + }); + + // Create a new object with the no-longer-used pk of 1 + realm->begin_transaction(); + any_cast<AnyDict&>(values)["pk"] = INT64_C(1); + any_cast<AnyDict&>(values)["int"] = INT64_C(4); + object_schema = realm->schema().find("all types"); + Object::create(ctx, realm, *object_schema, values); + realm->commit_transaction(); + + // Verify results + auto table = get_table(realm, "all types"); + REQUIRE(table->size() == 11); + REQUIRE(table->get_primary_key_column() == table->get_column_key("pk")); + for (int i = 0; i < 10; ++i) { + auto obj = table->get_object(i); + REQUIRE(obj.get<int64_t>("pk") == i + 2); + REQUIRE(obj.get<int64_t>("int") == i + 5); + } + auto obj = table->get_object(10); + REQUIRE(obj.get<int64_t>("pk") == 1); + REQUIRE(obj.get<int64_t>("int") == 4); + } + + SECTION("modify existing string primary key values in migration") { + // Create several objects to increase the chance of things + // actually breaking if we're doing invalid things + CppContext ctx(realm); + auto object_schema = realm->schema().find("string pk"); + realm->begin_transaction(); + for (int64_t i = 0; i < 10; ++i) { + util::Any values = AnyDict{ + {"pk", util::to_string(i)}, + {"value", i + 1}, + }; + Object::create(ctx, realm, *object_schema, values); + } + realm->commit_transaction(); + + // Increase the PK of each object by one in a migration + realm->update_schema(schema, 2, [](auto, auto new_realm, Schema&) { + CppContext ctx(new_realm); + Results results(new_realm, get_table(new_realm, "string pk")); + for (size_t i = 0, count = results.size(); i < count; ++i) { + Object obj(new_realm, results.get<Obj>(i)); + util::Any v = util::to_string(any_cast<int64_t>(obj.get_property_value<util::Any>(ctx, "value"))); + obj.set_property_value(ctx, "pk", v); + } + }); + + // Create a new object with the no-longer-used pk of 0 + realm->begin_transaction(); + util::Any values = AnyDict{ + {"pk", "0"s}, + {"value", INT64_C(0)}, + }; + object_schema = realm->schema().find("string pk"); + Object::create(ctx, realm, *object_schema, values); + realm->commit_transaction(); + + // Verify results + auto table = get_table(realm, "string pk"); + REQUIRE(table->size() == 11); + REQUIRE(table->get_primary_key_column() == table->get_column_key("pk")); + for (auto& obj : *table) { + REQUIRE(util::to_string(obj.get<int64_t>("value")).c_str() == obj.get<StringData>("pk")); + } + } + + SECTION("create and modify int primary key inside migration") { + SECTION("with index") { + realm->begin_transaction(); + auto table = get_table(realm, "int pk"); + table->add_search_index(table->get_column_key("pk")); + realm->commit_transaction(); + } + SECTION("no index") { + } + + realm->update_schema(schema, 2, [](auto, auto new_realm, Schema&) { + CppContext ctx(new_realm); + for (int64_t i = 0; i < 10; ++i) { + auto obj = Object::create(ctx, new_realm, *new_realm->schema().find("int pk"), + util::Any(AnyDict{ + {"pk", INT64_C(0)}, + {"value", i} + })); + obj.set_property_value(ctx, "pk", util::Any(i)); + } + }); + + auto table = get_table(realm, "int pk"); + REQUIRE(table->size() == 10); + REQUIRE(table->get_primary_key_column() == table->get_column_key("pk")); + for (int i = 0; i < 10; ++i) { + auto obj = table->get_object(i); + REQUIRE(obj.get<int64_t>("pk") == i); + REQUIRE(obj.get<int64_t>("value") == i); + } + } + + SECTION("create and modify string primary key inside migration") { + SECTION("with index") { + realm->begin_transaction(); + auto table = get_table(realm, "string pk"); + table->add_search_index(table->get_column_key("pk")); + realm->commit_transaction(); + } + SECTION("no index") { + } + + realm->update_schema(schema, 2, [](auto, auto new_realm, Schema&) { + CppContext ctx(new_realm); + for (int64_t i = 0; i < 10; ++i) { + auto obj = Object::create(ctx, new_realm, *new_realm->schema().find("string pk"), + util::Any(AnyDict{ + {"pk", ""s}, + {"value", i} + })); + obj.set_property_value(ctx, "pk", util::Any(util::to_string(i))); + } + }); + + auto table = get_table(realm, "string pk"); + REQUIRE(table->size() == 10); + REQUIRE(table->get_primary_key_column() == table->get_column_key("pk")); + for (auto& obj : *table) + REQUIRE(obj.get<StringData>("pk") == util::to_string(obj.get<int64_t>("value")).c_str()); + } + + SECTION("create object after adding primary key") { + schema = set_primary_key(schema, "all types", ""); + realm->update_schema(schema, 2); + schema = set_primary_key(schema, "all types", "pk"); + REQUIRE_NOTHROW(realm->update_schema(schema, 3, [&](auto, auto new_realm, Schema&) { + CppContext ctx(new_realm); + any_cast<AnyDict&>(values)["pk"] = INT64_C(2); + Object::create(ctx, realm, "all types", values); + })); + } } SECTION("property renaming") { @@ -1132,6 +1315,27 @@ TEST_CASE("migration: Automatic") { schema = set_indexed(schema, "object", "value", true); SUCCESSFUL_RENAME(schema, schema2, {"object", "value", "new"}); } + + SECTION("create object inside migration after renaming pk") { + schema = set_primary_key(schema, "object", "value"); + auto new_schema = set_primary_key(rename_value(schema), "object", "new"); + init(schema); + REQUIRE_NOTHROW(realm->update_schema(new_schema, 2, [](auto, auto realm, Schema& schema) { + ObjectStore::rename_property(realm->read_group(), schema, + "object", "value", "new"); + + CppContext ctx(realm); + util::Any values = AnyDict{{"new", INT64_C(11)}}; + Object::create(ctx, realm, "object", values); + })); + REQUIRE(realm->schema() == new_schema); + VERIFY_SCHEMA(*realm, false); + auto table = ObjectStore::table_for_object_type(realm->read_group(), "object"); + auto key = table->get_column_keys()[0]; + auto it = table->begin(); + REQUIRE(it->get<int64_t>(key) == 10); + REQUIRE((++it)->get<int64_t>(key) == 11); + } } } diff --git a/Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist b/Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist index 9b175f919..d02e33db9 100644 --- a/Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist +++ b/Carthage/Checkouts/realm-cocoa/Realm/Realm-Info.plist @@ -17,11 +17,11 @@ <key>CFBundlePackageType</key> <string>FMWK</string> <key>CFBundleShortVersionString</key> - <string>5.2.0</string> + <string>5.3.2</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> - <string>5.2.0</string> + <string>5.3.2</string> <key>NSHumanReadableCopyright</key> <string>Copyright © 2014 Realm. All rights reserved.</string> <key>NSPrincipalClass</key> diff --git a/Carthage/Checkouts/realm-cocoa/build.sh b/Carthage/Checkouts/realm-cocoa/build.sh index f65bea368..8cd328465 100755 --- a/Carthage/Checkouts/realm-cocoa/build.sh +++ b/Carthage/Checkouts/realm-cocoa/build.sh @@ -1551,7 +1551,7 @@ x.y.z Release notes (yyyy-MM-dd) * Realm Object Server: 3.21.0 or later. * Realm Studio: 3.11 or later. * APIs are backwards compatible with all previous releases in the 5.x.y series. -* Carthage release for Swift is built with Xcode 11.5. +* Carthage release for Swift is built with Xcode 11.6. ### Internal * Upgraded realm-core from ? to ? diff --git a/Carthage/Checkouts/realm-cocoa/dependencies.list b/Carthage/Checkouts/realm-cocoa/dependencies.list index 876eb6eb8..3355050ec 100644 --- a/Carthage/Checkouts/realm-cocoa/dependencies.list +++ b/Carthage/Checkouts/realm-cocoa/dependencies.list @@ -1,4 +1,4 @@ -VERSION=5.2.0 -REALM_CORE_VERSION=6.0.8 -REALM_SYNC_VERSION=5.0.7 +VERSION=5.3.2 +REALM_CORE_VERSION=6.0.12 +REALM_SYNC_VERSION=5.0.12 REALM_OBJECT_SERVER_VERSION=3.28.5 diff --git a/Carthage/Checkouts/realm-cocoa/examples/installation/build.sh b/Carthage/Checkouts/realm-cocoa/examples/installation/build.sh index 88363d502..10de66d68 100755 --- a/Carthage/Checkouts/realm-cocoa/examples/installation/build.sh +++ b/Carthage/Checkouts/realm-cocoa/examples/installation/build.sh @@ -40,9 +40,6 @@ command: test-watchos-swift-xcframework: tests watchOS Swift xcframework example. test-watchos-swift-cocoapods: tests watchOS Swift CocoaPods example. test-watchos-swift-carthage: tests watchOS Swift Carthage example. - test-watchos-spm: tests watchOS Swift Package Manager example. - - test-tvos-spm: tests tvOS Swift Package Manager example. EOF } @@ -167,11 +164,9 @@ case "$COMMAND" in for target in ios-swift-dynamic ios-swift-cocoapods osx-swift-dynamic ios-swift-carthage osx-swift-carthage; do ./build.sh test-$target || exit 1 done - if (( $(xcode_version_major) >= 11 )); then - for target in ios osx watchos tvos; do - ./build.sh test-$target-spm || exit 1 - done - fi + for target in ios osx; do + ./build.sh test-$target-spm || exit 1 + done ;; test-*-*-cocoapods) @@ -199,6 +194,13 @@ case "$COMMAND" in ;; test-ios-spm) + # We have to "hide" the spm example from carthage because otherwise + # it'll fetch the example's package dependencies as part of deciding + # what to build from this repo. + if ! [ -L ios/swift/SwiftPackageManagerExample/SwiftPackageManagerExample.xcodeproj/project.pbxproj ]; then + mkdir -p ios/swift/SwiftPackageManagerExample/SwiftPackageManagerExample.xcodeproj + ln -s ../project.pbxproj ios/swift/SwiftPackageManagerExample/SwiftPackageManagerExample.xcodeproj + fi xctest "$PLATFORM" swift SwiftPackageManagerExample ;; diff --git a/Carthage/Checkouts/realm-cocoa/scripts/package_examples.rb b/Carthage/Checkouts/realm-cocoa/scripts/package_examples.rb index 986ce90c8..d383a2a5f 100755 --- a/Carthage/Checkouts/realm-cocoa/scripts/package_examples.rb +++ b/Carthage/Checkouts/realm-cocoa/scripts/package_examples.rb @@ -41,7 +41,7 @@ base_examples = [ "examples/tvos/swift", ] -xcode_versions = %w(11.3 11.4.1 11.5) +xcode_versions = %w(11.3 11.4.1 11.5 11.6) # Remove reference to Realm.xcodeproj from all example workspaces. base_examples.each do |example| diff --git a/File Provider Extension/FileProviderData.swift b/File Provider Extension/FileProviderData.swift index 3b3b3e1b3..43420b8a6 100644 --- a/File Provider Extension/FileProviderData.swift +++ b/File Provider Extension/FileProviderData.swift @@ -153,43 +153,6 @@ class fileProviderData: NSObject { } // MARK: - - - func updateFavoriteForWorkingSet() { - - var updateWorkingSet = false - let oldListFavoriteIdentifierRank = listFavoriteIdentifierRank - listFavoriteIdentifierRank = NCManageDatabase.sharedInstance.getTableMetadatasDirectoryFavoriteIdentifierRank(account: account) - - // (ADD) - for (identifier, _) in listFavoriteIdentifierRank { - - guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", identifier)) else { continue } - guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: homeServerUrl) else { continue } - let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier) - - fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item - updateWorkingSet = true - } - - // (REMOVE) - for (identifier, _) in oldListFavoriteIdentifierRank { - - if !listFavoriteIdentifierRank.keys.contains(identifier) { - - guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", identifier)) else { continue } - let itemIdentifier = fileProviderUtility.sharedInstance.getItemIdentifier(metadata: metadata) - - fileProviderSignalDeleteWorkingSetItemIdentifier[itemIdentifier] = itemIdentifier - updateWorkingSet = true - } - } - - if updateWorkingSet { - signalEnumerator(for: [.workingSet]) - } - } - - // MARK: - // Convinent method to signal the enumeration for containers. // @@ -206,4 +169,41 @@ class fileProviderData: NSObject { } } } + + /* + func updateFavoriteForWorkingSet() { + + var updateWorkingSet = false + let oldListFavoriteIdentifierRank = listFavoriteIdentifierRank + listFavoriteIdentifierRank = NCManageDatabase.sharedInstance.getTableMetadatasDirectoryFavoriteIdentifierRank(account: account) + + // (ADD) + for (identifier, _) in listFavoriteIdentifierRank { + + guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", identifier)) else { continue } + guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: homeServerUrl) else { continue } + let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier) + + fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item + updateWorkingSet = true + } + + // (REMOVE) + for (identifier, _) in oldListFavoriteIdentifierRank { + + if !listFavoriteIdentifierRank.keys.contains(identifier) { + + guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", identifier)) else { continue } + let itemIdentifier = fileProviderUtility.sharedInstance.getItemIdentifier(metadata: metadata) + + fileProviderSignalDeleteWorkingSetItemIdentifier[itemIdentifier] = itemIdentifier + updateWorkingSet = true + } + } + + if updateWorkingSet { + signalEnumerator(for: [.workingSet]) + } + } + */ } diff --git a/File Provider Extension/FileProviderEnumerator.swift b/File Provider Extension/FileProviderEnumerator.swift index f830da14c..f402efab0 100644 --- a/File Provider Extension/FileProviderEnumerator.swift +++ b/File Provider Extension/FileProviderEnumerator.swift @@ -112,14 +112,9 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator { } else { - readFileOrFolder(serverUrl: serverUrl) { - let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), page: 1, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true) - + self.readFileOrFolder(serverUrl: serverUrl) { (metadatas) in self.completeObserver(observer, numPage: 1, metadatas: metadatas) - } - - // Update the WorkingSet -> Favorite - fileProviderData.sharedInstance.updateFavoriteForWorkingSet() + } } } else { @@ -133,10 +128,8 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator { } } else { - - let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), page: numPage, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true) - - completeObserver(observer, numPage: numPage, metadatas: metadatas) + + completeObserver(observer, numPage: numPage, metadatas: nil) } } } @@ -222,55 +215,43 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator { } } - func readFileOrFolder(serverUrl: String, completionHandler: @escaping () -> Void) { + func readFileOrFolder(serverUrl: String, completionHandler: @escaping (_ metadatas: [tableMetadata]?) -> Void) { + + var directoryEtag: String? - NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles(), completionHandler: { (account, files, responseData, errorCode, errorDescription) in + if let tableDirectory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl)) { + directoryEtag = tableDirectory.etag + } - var needReadFolder = true + NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in - if let tableDirectory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) { - if errorCode == 0 && files != nil && files!.count == 1 { - if tableDirectory.etag == files![0].etag { - needReadFolder = false - } - } - } + if directoryEtag != files.first?.etag { - if needReadFolder { - - NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: CCUtility.getShowHiddenFiles(), completionHandler: { (account, files, responseData, errorCode, errorDescription) in + NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in - if errorCode == 0 && files != nil { - - let fileFolder = files![0] - - // Add directory - NCManageDatabase.sharedInstance.addDirectory(encrypted: fileFolder.e2eEncrypted, favorite: fileFolder.favorite, ocId: fileFolder.ocId, fileId: fileFolder.fileId, etag: fileFolder.etag, permissions: fileFolder.permissions, serverUrl: serverUrl, richWorkspace: fileFolder.richWorkspace, account: account) - - // Save status transfer metadata - let metadatasInDownload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", account, serverUrl, k_metadataStatusWaitDownload, k_metadataStatusInDownload, k_metadataStatusDownloading, k_metadataStatusDownloadError)) - - let metadatasInUpload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", account, serverUrl, k_metadataStatusWaitUpload, k_metadataStatusInUpload, k_metadataStatusUploading, k_metadataStatusUploadError)) - - // Delete metadata - NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, k_metadataStatusNormal)) - - // Add metadata - NCManageDatabase.sharedInstance.addMetadatas(files: files, account: account) - - if metadatasInDownload != nil { - NCManageDatabase.sharedInstance.addMetadatas(metadatasInDownload!) - } - if metadatasInUpload != nil { - NCManageDatabase.sharedInstance.addMetadatas(metadatasInUpload!) + if errorCode == 0 { + DispatchQueue.global().async { + NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: true, account: account) { (metadataFolder, metadatasFolder, metadatas) in + let metadatasResult = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, k_metadataStatusNormal)) + NCManageDatabase.sharedInstance.updateMetadatas(metadatas, metadatasResult: metadatasResult) + for metadata in metadatasFolder { + let serverUrl = metadata.serverUrl + "/" + metadata.fileNameView + NCManageDatabase.sharedInstance.addDirectory(encrypted: metadata.e2eEncrypted, favorite: metadata.favorite, ocId: metadata.ocId, fileId: metadata.fileId, etag: nil, permissions: metadata.permissions, serverUrl: serverUrl, richWorkspace: metadata.richWorkspace, account: metadata.account) + } + let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), sorted: "fileName", ascending: true) + completionHandler(metadatas) + } } + } else { + let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), sorted: "fileName", ascending: true) + completionHandler(metadatas) } - completionHandler() - }) + } } else { - completionHandler() + let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), sorted: "fileName", ascending: true) + completionHandler(metadatas) } - }) + } } func getPagination(endpoint:String, serverUrl: String, page: Int, limit: Int, completionHandler: @escaping (_ metadatas: [tableMetadata]?) -> Void) { @@ -280,34 +261,48 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator { if fileNamePath == "" { fileNamePath = "/" } + var directoryEtag: String? - NCCommunication.shared.iosHelper(fileNamePath: fileNamePath, serverUrl: serverUrl, offset: offset, limit: limit) { (account, files, errorCode, errorDescription) in - - if errorCode == 0 && files != nil && files!.count >= 1 { + if let tableDirectory = NCManageDatabase.sharedInstance.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl)) { + if page == 1 { + directoryEtag = tableDirectory.etag + } + } + + NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in + + if errorCode == 0 && files.count == 1 && directoryEtag != files.first?.etag { + + if page == 1 { + let metadataFolder = NCManageDatabase.sharedInstance.convertNCFileToMetadata(files[0], isEncrypted: false, account: account) + NCManageDatabase.sharedInstance.addMetadata(metadataFolder) + NCManageDatabase.sharedInstance.addDirectory(encrypted: metadataFolder.e2eEncrypted, favorite: metadataFolder.favorite, ocId: metadataFolder.ocId, fileId: metadataFolder.fileId, etag: metadataFolder.etag, permissions: metadataFolder.permissions, serverUrl: serverUrl, richWorkspace: metadataFolder.richWorkspace, account: metadataFolder.account) + } - NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files!, useMetadataFolder: false, account: account) { (metadataFolder, metadatasFolder, metadatas) in - - // Prepare DB - if offset == 0 { - NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, k_metadataStatusNormal)) - let metadatasInDownload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", account, serverUrl, k_metadataStatusWaitDownload, k_metadataStatusInDownload, k_metadataStatusDownloading, k_metadataStatusDownloadError)) - let metadatasInUpload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", account, serverUrl, k_metadataStatusWaitUpload, k_metadataStatusInUpload, k_metadataStatusUploading, k_metadataStatusUploadError)) - if metadatasInDownload != nil { - NCManageDatabase.sharedInstance.addMetadatas(metadatasInDownload!) - } - if metadatasInUpload != nil { - NCManageDatabase.sharedInstance.addMetadatas(metadatasInUpload!) + NCCommunication.shared.iosHelper(fileNamePath: fileNamePath, serverUrl: serverUrl, offset: offset, limit: limit) { (account, files, errorCode, errorDescription) in + + if errorCode == 0 { + DispatchQueue.global().async { + NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: false, account: account) { (metadataFolder, metadatasFolder, metadatas) in + let metadatasResult = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", fileProviderData.sharedInstance.account, serverUrl, k_metadataStatusNormal), page: page, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true) + NCManageDatabase.sharedInstance.updateMetadatas(metadatas, metadatasResult: metadatasResult) + for metadata in metadatasFolder { + let serverUrl = metadata.serverUrl + "/" + metadata.fileNameView + NCManageDatabase.sharedInstance.addDirectory(encrypted: metadata.e2eEncrypted, favorite: metadata.favorite, ocId: metadata.ocId, fileId: metadata.fileId, etag: nil, permissions: metadata.permissions, serverUrl: serverUrl, richWorkspace: nil, account: metadata.account) + } + let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), page: page, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true) + completionHandler(metadatas) + } } + } else { + let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), page: page, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true) + completionHandler(metadatas) } - - NCManageDatabase.sharedInstance.addMetadatas(metadatas) } + } else { + let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), sorted: "fileName", ascending: true) + completionHandler(metadatas) } - - let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.sharedInstance.account, serverUrl), page: page, limit: fileProviderData.sharedInstance.itemForPage, sorted: "fileName", ascending: true) - - completionHandler(metadatas) } } - } diff --git a/File Provider Extension/FileProviderExtension+Actions.swift b/File Provider Extension/FileProviderExtension+Actions.swift index 3f16aa443..5e8c1355b 100644 --- a/File Provider Extension/FileProviderExtension+Actions.swift +++ b/File Provider Extension/FileProviderExtension+Actions.swift @@ -40,35 +40,34 @@ extension FileProviderExtension { if errorCode == 0 { - let metadata = tableMetadata() - - metadata.account = account - metadata.directory = true - metadata.ocId = ocId! - metadata.fileId = "" - metadata.fileName = directoryName - metadata.fileNameView = directoryName - metadata.serverUrl = tableDirectory.serverUrl - metadata.typeFile = k_metadataTypeFile_directory - - guard let metadataUpdate = NCManageDatabase.sharedInstance.addMetadata(metadata) else { - completionHandler(nil, NSFileProviderError(.noSuchItem)) - return - } - - guard let _ = NCManageDatabase.sharedInstance.addDirectory(encrypted: false, favorite: false, ocId: ocId!, fileId: "", etag: nil, permissions: nil, serverUrl: tableDirectory.serverUrl + "/" + directoryName, richWorkspace: nil, account: account) else { - completionHandler(nil, NSFileProviderError(.noSuchItem)) - return - } - - guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadataUpdate, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else { - completionHandler(nil, NSFileProviderError(.noSuchItem)) - return + NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in + + if errorCode == 0 && files.count > 0 { + + let file = files.first! + let metadata = NCManageDatabase.sharedInstance.convertNCFileToMetadata(file, isEncrypted: false, account: fileProviderData.sharedInstance.account) + + NCManageDatabase.sharedInstance.addDirectory(encrypted: false, favorite: false, ocId: ocId!, fileId: metadata.fileId, etag: metadata.etag, permissions: metadata.permissions, serverUrl: serverUrlFileName, richWorkspace: metadata.richWorkspace, account: metadata.account) + NCManageDatabase.sharedInstance.addMetadata(metadata) + + guard let metadataInsert = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId!)) else { + completionHandler(nil, NSFileProviderError(.noSuchItem)) + return + } + + guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadataInsert, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else { + completionHandler(nil, NSFileProviderError(.noSuchItem)) + return + } + + let item = FileProviderItem(metadata: metadataInsert, parentItemIdentifier: parentItemIdentifier) + completionHandler(item, nil) + + } else { + completionHandler(nil, NSFileProviderError(.serverUnreachable)) + } } - let item = FileProviderItem(metadata: metadataUpdate, parentItemIdentifier: parentItemIdentifier) - completionHandler(item, nil) - } else { completionHandler(nil, NSFileProviderError(.serverUnreachable)) } @@ -82,7 +81,11 @@ extension FileProviderExtension { return } + let ocId = metadata.ocId let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName + let isDirectory = metadata.directory + let serverUrl = metadata.serverUrl; + let fileName = metadata.fileName; NCCommunication.shared.deleteFileOrFolder(serverUrlFileName) { (account, errorCode, errorDescription) in @@ -95,13 +98,13 @@ extension FileProviderExtension { print("error: \(error)") } - if metadata.directory { - let dirForDelete = CCUtility.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName) + if isDirectory { + let dirForDelete = CCUtility.stringAppendServerUrl(serverUrl, addFileName: fileName) NCManageDatabase.sharedInstance.deleteDirectoryAndSubDirectory(serverUrl: dirForDelete!, account: account) } - NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) - NCManageDatabase.sharedInstance.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) + NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", ocId)) + NCManageDatabase.sharedInstance.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", ocId)) completionHandler(nil) @@ -143,7 +146,7 @@ extension FileProviderExtension { NCManageDatabase.sharedInstance.renameDirectory(ocId: ocIdFrom, serverUrl: serverUrlTo) } - _ = NCManageDatabase.sharedInstance.moveMetadata(ocId: ocIdFrom, serverUrlTo: serverUrlTo) + NCManageDatabase.sharedInstance.moveMetadata(ocId: ocIdFrom, serverUrlTo: serverUrlTo) guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdFrom)) else { completionHandler(nil, NSFileProviderError(.noSuchItem)) @@ -174,13 +177,16 @@ extension FileProviderExtension { let fileNameFrom = metadata.fileNameView let fileNamePathFrom = metadata.serverUrl + "/" + fileNameFrom let fileNamePathTo = metadata.serverUrl + "/" + itemName + let ocId = metadata.ocId NCCommunication.shared.moveFileOrFolder(serverUrlFileNameSource: fileNamePathFrom, serverUrlFileNameDestination: fileNamePathTo, overwrite: false) { (account, errorCode, errorDescription) in if errorCode == 0 { // Rename metadata - guard let metadata = NCManageDatabase.sharedInstance.renameMetadata(fileNameTo: itemName, ocId: metadata.ocId) else { + NCManageDatabase.sharedInstance.renameMetadata(fileNameTo: itemName, ocId: ocId) + + guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId)) else { completionHandler(nil, NSFileProviderError(.noSuchItem)) return } @@ -200,7 +206,7 @@ extension FileProviderExtension { _ = fileProviderUtility.sharedInstance.moveFile(CCUtility.getDirectoryProviderStorageIconOcId(itemIdentifier.rawValue, etag: metadata.etag), toPath: CCUtility.getDirectoryProviderStorageIconOcId(itemIdentifier.rawValue, etag: metadata.etag)) - NCManageDatabase.sharedInstance.setLocalFile(ocId: metadata.ocId, date: nil, exifDate: nil, exifLatitude: nil, exifLongitude: nil, fileName: itemName, etag: nil) + NCManageDatabase.sharedInstance.setLocalFile(ocId: ocId, date: nil, exifDate: nil, exifLatitude: nil, exifLongitude: nil, fileName: itemName, etag: nil) } guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else { @@ -208,7 +214,7 @@ extension FileProviderExtension { return } - let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier) + let item = FileProviderItem(metadata: metadata.freeze(), parentItemIdentifier: parentItemIdentifier) completionHandler(item, nil) } else { @@ -230,6 +236,8 @@ extension FileProviderExtension { } var favorite = false + let ocId = metadata.ocId + if favoriteRank == nil { fileProviderData.sharedInstance.listFavoriteIdentifierRank.removeValue(forKey: itemIdentifier.rawValue) } else { @@ -244,20 +252,32 @@ extension FileProviderExtension { let fileNamePath = CCUtility.returnFileNamePath(fromFileName: metadata.fileName, serverUrl: metadata.serverUrl, activeUrl: fileProviderData.sharedInstance.accountUrl)! NCCommunication.shared.setFavorite(fileName: fileNamePath, favorite: favorite) { (account, errorCode, errorDescription) in + if errorCode == 0 { - // Change DB - metadata.favorite = favorite - guard let metadataUpdate = NCManageDatabase.sharedInstance.addMetadata(metadata) else { + + guard let metadataTemp = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId)) else { completionHandler(nil, NSFileProviderError(.noSuchItem)) return } - let item = FileProviderItem(metadata: metadataUpdate, parentItemIdentifier: parentItemIdentifier) + let metadata = tableMetadata.init(value: metadataTemp) + + // Change DB + metadata.favorite = favorite + NCManageDatabase.sharedInstance.addMetadata(metadata) + let item = FileProviderItem(metadata: metadata.freeze(), parentItemIdentifier: parentItemIdentifier) fileProviderData.sharedInstance.fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item fileProviderData.sharedInstance.signalEnumerator(for: [.workingSet]) completionHandler(item, nil) + } else { + + guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId)) else { + completionHandler(nil, NSFileProviderError(.noSuchItem)) + return + } + // Errore, remove from listFavoriteIdentifierRank fileProviderData.sharedInstance.listFavoriteIdentifierRank.removeValue(forKey: itemIdentifier.rawValue) let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier) @@ -273,13 +293,20 @@ extension FileProviderExtension { override func setTagData(_ tagData: Data?, forItemIdentifier itemIdentifier: NSFileProviderItemIdentifier, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) { - guard let metadata = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(itemIdentifier) else { + guard let metadataForTag = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(itemIdentifier) else { completionHandler(nil, NSFileProviderError(.noSuchItem)) return } + let ocId = metadataForTag.ocId + let account = metadataForTag.account // Add, Remove (nil) - NCManageDatabase.sharedInstance.addTag(metadata.ocId, tagIOS: tagData, account: metadata.account) + NCManageDatabase.sharedInstance.addTag(ocId, tagIOS: tagData, account: account) + + guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId)) else { + completionHandler(nil, NSFileProviderError(.noSuchItem)) + return + } guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else { completionHandler(nil, NSFileProviderError(.noSuchItem)) diff --git a/File Provider Extension/FileProviderExtension+NetworkingDelegate.swift b/File Provider Extension/FileProviderExtension+NetworkingDelegate.swift index 2b20e82c1..ec9802e85 100644 --- a/File Provider Extension/FileProviderExtension+NetworkingDelegate.swift +++ b/File Provider Extension/FileProviderExtension+NetworkingDelegate.swift @@ -29,7 +29,8 @@ extension FileProviderExtension: NCNetworkingDelegate { func uploadComplete(fileName: String, serverUrl: String, ocId: String?, etag: String?, date: NSDate?, size: Int64, description: String?, task: URLSessionTask, errorCode: Int, errorDescription: String) { guard let ocIdTemp = description else { return } - guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp)) else { return } + guard let metadataTemp = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp)) else { return } + let metadata = tableMetadata.init(value: metadataTemp) let url = URL(fileURLWithPath: CCUtility.getDirectoryProviderStorageOcId(ocIdTemp, fileNameView: fileName)) DispatchQueue.main.asyncAfter(deadline: .now() + 1) { @@ -39,9 +40,7 @@ extension FileProviderExtension: NCNetworkingDelegate { if errorCode == 0 { - guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else { - return - } + guard let parentItemIdentifier = fileProviderUtility.sharedInstance.getParentItemIdentifier(metadata: metadata, homeServerUrl: fileProviderData.sharedInstance.homeServerUrl) else { return } var item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier) // New file @@ -51,7 +50,7 @@ extension FileProviderExtension: NCNetworkingDelegate { fileProviderData.sharedInstance.fileProviderSignalDeleteWorkingSetItemIdentifier[item.itemIdentifier] = item.itemIdentifier fileProviderData.sharedInstance.signalEnumerator(for: [parentItemIdentifier, .workingSet]) } - + metadata.fileName = fileName metadata.serverUrl = serverUrl if let etag = etag { metadata.etag = etag } @@ -61,8 +60,8 @@ extension FileProviderExtension: NCNetworkingDelegate { metadata.size = Double(size) metadata.status = Int(k_metadataStatusNormal) - guard let metadataUpdated = NCManageDatabase.sharedInstance.addMetadata(metadata) else { return } - _ = NCManageDatabase.sharedInstance.addLocalFile(metadata: metadataUpdated) + NCManageDatabase.sharedInstance.addMetadata(metadata) + NCManageDatabase.sharedInstance.addLocalFile(metadata: metadata) // New file if ocId != ocIdTemp { @@ -76,7 +75,7 @@ extension FileProviderExtension: NCNetworkingDelegate { } // Signal update - item = FileProviderItem(metadata: metadataUpdated, parentItemIdentifier: parentItemIdentifier) + item = FileProviderItem(metadata: metadata.freeze(), parentItemIdentifier: parentItemIdentifier) fileProviderData.sharedInstance.fileProviderSignalUpdateContainerItem[item.itemIdentifier] = item fileProviderData.sharedInstance.fileProviderSignalUpdateWorkingSetItem[item.itemIdentifier] = item fileProviderData.sharedInstance.signalEnumerator(for: [parentItemIdentifier, .workingSet]) diff --git a/File Provider Extension/FileProviderExtension.swift b/File Provider Extension/FileProviderExtension.swift index bf11e39d6..5a57c30eb 100644 --- a/File Provider Extension/FileProviderExtension.swift +++ b/File Provider Extension/FileProviderExtension.swift @@ -211,10 +211,11 @@ class FileProviderExtension: NSFileProviderExtension { return } - guard var metadata = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(identifier) else { + guard let metadata = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(identifier) else { completionHandler(NSFileProviderError(.noSuchItem)) return } + let tableLocalFile = NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) if tableLocalFile != nil && CCUtility.fileProviderStorageExists(metadata.ocId, fileNameView: metadata.fileNameView) && tableLocalFile?.etag == metadata.etag { completionHandler(nil) @@ -226,8 +227,12 @@ class FileProviderExtension: NSFileProviderExtension { NCCommunication.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, requestHandler: { (request) in - metadata.status = Int(k_metadataStatusDownloading) - if let result = NCManageDatabase.sharedInstance.addMetadata(metadata) { metadata = result } + if var metadata = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(identifier) { + metadata = tableMetadata.init(value: metadata) + metadata.status = Int(k_metadataStatusDownloading) + NCManageDatabase.sharedInstance.addMetadata(metadata) + } + downloadRequest = request self.outstandingSessionTasks[url] = task @@ -242,6 +247,11 @@ class FileProviderExtension: NSFileProviderExtension { }) { (account, etag, date, length, error, errorCode, errorDescription) in self.outstandingSessionTasks.removeValue(forKey: url) + guard var metadata = fileProviderUtility.sharedInstance.getTableMetadataFromItemIdentifier(identifier) else { + completionHandler(NSFileProviderError(.noSuchItem)) + return + } + metadata = tableMetadata.init(value: metadata) if errorCode == 0 { @@ -250,7 +260,7 @@ class FileProviderExtension: NSFileProviderExtension { metadata.etag = etag ?? "" NCManageDatabase.sharedInstance.addLocalFile(metadata: metadata) - if let result = NCManageDatabase.sharedInstance.addMetadata(metadata) { metadata = result } + NCManageDatabase.sharedInstance.addMetadata(metadata) completionHandler(nil) @@ -356,15 +366,12 @@ class FileProviderExtension: NSFileProviderExtension { fileURL.stopAccessingSecurityScopedResource() - let metadata = NCManageDatabase.sharedInstance.createMetadata(account: fileProviderData.sharedInstance.account, fileName: fileName, ocId: ocIdTemp, serverUrl: tableDirectory.serverUrl, url: "", contentType: "") + let metadata = NCManageDatabase.sharedInstance.createMetadata(account: fileProviderData.sharedInstance.account, fileName: fileName, ocId: ocIdTemp, serverUrl: tableDirectory.serverUrl, urlBase: fileProviderData.sharedInstance.accountUrl, url: "", contentType: "") metadata.session = NCCommunicationCommon.shared.sessionIdentifierExtension metadata.size = size metadata.status = Int(k_metadataStatusInUpload) - guard let metadataForUpload = NCManageDatabase.sharedInstance.addMetadata(metadata) else { - completionHandler(nil, NSFileProviderError(.noSuchItem)) - return - } + NCManageDatabase.sharedInstance.addMetadata(metadata) let serverUrlFileName = tableDirectory.serverUrl + "/" + fileName let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(ocIdTemp, fileNameView: fileName)! @@ -374,7 +381,7 @@ class FileProviderExtension: NSFileProviderExtension { NSFileProviderManager.default.register(task, forItemWithIdentifier: NSFileProviderItemIdentifier(ocIdTemp)) { (error) in } } - let item = FileProviderItem(metadata: metadataForUpload, parentItemIdentifier: parentItemIdentifier) + let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier) completionHandler(item, nil) } } diff --git a/File Provider Extension/FileProviderItem.swift b/File Provider Extension/FileProviderItem.swift index 5a41214ac..3867784f7 100644 --- a/File Provider Extension/FileProviderItem.swift +++ b/File Provider Extension/FileProviderItem.swift @@ -43,10 +43,6 @@ class FileProviderItem: NSObject, NSFileProviderItem { var typeIdentifier: String { let results = NCCommunicationCommon.shared.getInternalContenType(fileName: metadata.fileNameView, contentType: "", directory: metadata.directory) - metadata.contentType = results.contentType - metadata.iconName = results.iconName - metadata.typeFile = results.typeFile - return results.typeIdentifier } diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj index a73440c0d..67c79e43d 100755 --- a/Nextcloud.xcodeproj/project.pbxproj +++ b/Nextcloud.xcodeproj/project.pbxproj @@ -47,6 +47,8 @@ F7063DF12199E56F003F38DA /* CocoaLumberjackSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7063DF02199E56E003F38DA /* CocoaLumberjackSwift.framework */; }; F707C26521A2DC5200F6181E /* NCStoreReview.swift in Sources */ = {isa = PBXBuildFile; fileRef = F707C26421A2DC5200F6181E /* NCStoreReview.swift */; }; F70968A424212C4E00ED60E5 /* NCLivePhoto.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70968A324212C4E00ED60E5 /* NCLivePhoto.swift */; }; + F70A58BE24D0349500DED00D /* NCCapabilitiesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70A58BD24D0349500DED00D /* NCCapabilitiesViewController.swift */; }; + F70A58C024D0545100DED00D /* NCCapabilitiesViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F70A58BF24D0545100DED00D /* NCCapabilitiesViewController.storyboard */; }; F70BFC7420E0FA7D00C67599 /* NCUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70BFC7320E0FA7C00C67599 /* NCUtility.swift */; }; F70BFC7520E0FA7D00C67599 /* NCUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70BFC7320E0FA7C00C67599 /* NCUtility.swift */; }; F70CAE3A1F8CF31A008125FD /* NCEndToEndEncryption.m in Sources */ = {isa = PBXBuildFile; fileRef = F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */; }; @@ -244,7 +246,6 @@ F7AE00F8230E81CB007ACF8A /* NCBrowserWeb.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7AE00F7230E81CB007ACF8A /* NCBrowserWeb.swift */; }; F7AE00FA230E81EB007ACF8A /* NCBrowserWeb.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7AE00F9230E81EB007ACF8A /* NCBrowserWeb.storyboard */; }; F7AF7633246BEDFE00B86E3C /* TOPasscodeViewController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7AF7632246BEDFE00B86E3C /* TOPasscodeViewController.framework */; }; - F7B0C0CD1EE7E7750033AC24 /* CCSynchronize.m in Sources */ = {isa = PBXBuildFile; fileRef = F7B0C0CC1EE7E7750033AC24 /* CCSynchronize.m */; }; F7B0C1751EE839A30033AC24 /* NCAutoUpload.m in Sources */ = {isa = PBXBuildFile; fileRef = F7B0C1741EE839A30033AC24 /* NCAutoUpload.m */; }; F7B174C822FAC0A8000B7579 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F7B174C722FAC0A8000B7579 /* AppDelegate.m */; }; F7B2DEF01F976854007CF4D2 /* NYMnemonic.m in Sources */ = {isa = PBXBuildFile; fileRef = F7B2DEEF1F976785007CF4D2 /* NYMnemonic.m */; }; @@ -388,6 +389,8 @@ F707C26421A2DC5200F6181E /* NCStoreReview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCStoreReview.swift; sourceTree = "<group>"; }; F70968A324212C4E00ED60E5 /* NCLivePhoto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCLivePhoto.swift; sourceTree = "<group>"; }; F70A07C8205285FB00DC1231 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Localizable.strings"; sourceTree = "<group>"; }; + F70A58BD24D0349500DED00D /* NCCapabilitiesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCapabilitiesViewController.swift; sourceTree = "<group>"; }; + F70A58BF24D0545100DED00D /* NCCapabilitiesViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCCapabilitiesViewController.storyboard; sourceTree = "<group>"; }; F70BFC7320E0FA7C00C67599 /* NCUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCUtility.swift; sourceTree = "<group>"; }; F70CAE381F8CF31A008125FD /* NCEndToEndEncryption.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NCEndToEndEncryption.h; sourceTree = "<group>"; }; F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NCEndToEndEncryption.m; sourceTree = "<group>"; }; @@ -620,8 +623,6 @@ F7AE00F7230E81CB007ACF8A /* NCBrowserWeb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCBrowserWeb.swift; sourceTree = "<group>"; }; F7AE00F9230E81EB007ACF8A /* NCBrowserWeb.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NCBrowserWeb.storyboard; sourceTree = "<group>"; }; F7AF7632246BEDFE00B86E3C /* TOPasscodeViewController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = TOPasscodeViewController.framework; path = Carthage/Build/iOS/TOPasscodeViewController.framework; sourceTree = "<group>"; }; - F7B0C0CB1EE7E7750033AC24 /* CCSynchronize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCSynchronize.h; sourceTree = "<group>"; }; - F7B0C0CC1EE7E7750033AC24 /* CCSynchronize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CCSynchronize.m; sourceTree = "<group>"; }; F7B0C1731EE839A30033AC24 /* NCAutoUpload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NCAutoUpload.h; sourceTree = "<group>"; }; F7B0C1741EE839A30033AC24 /* NCAutoUpload.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NCAutoUpload.m; sourceTree = "<group>"; }; F7B174C722FAC0A8000B7579 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; @@ -1132,6 +1133,8 @@ F7ACE4291BAC0268006C0017 /* Acknowledgements.h */, F7ACE42B1BAC0268006C0017 /* Acknowledgements.rtf */, F7ACE42A1BAC0268006C0017 /* Acknowledgements.m */, + F70A58BF24D0545100DED00D /* NCCapabilitiesViewController.storyboard */, + F70A58BD24D0349500DED00D /* NCCapabilitiesViewController.swift */, F7A321AB1E9E6AD50069AD1B /* CCAdvanced.h */, F7A321AC1E9E6AD50069AD1B /* CCAdvanced.m */, F7ACE42C1BAC0268006C0017 /* CCManageAccount.h */, @@ -1157,15 +1160,6 @@ path = BrowserWeb; sourceTree = "<group>"; }; - F7B0C0CA1EE7E7750033AC24 /* Synchronize */ = { - isa = PBXGroup; - children = ( - F7B0C0CB1EE7E7750033AC24 /* CCSynchronize.h */, - F7B0C0CC1EE7E7750033AC24 /* CCSynchronize.m */, - ); - path = Synchronize; - sourceTree = "<group>"; - }; F7B0C1701EE8397E0033AC24 /* AutoUpload */ = { isa = PBXGroup; children = ( @@ -1441,7 +1435,6 @@ F7ACE4281BAC0268006C0017 /* Settings */, F728CE741BF6322C00E69702 /* Share */, F7169A161EE590930086BD69 /* Shares */, - F7B0C0CA1EE7E7750033AC24 /* Synchronize */, F7E9C41320F4CA870040CF18 /* Transfers */, F78F74322163753B00C2ADAD /* Trash */, F70784811A2C8A0D00AC9FFF /* UploadFromOtherUpp */, @@ -1807,6 +1800,7 @@ F78ACD4B21903F850088454D /* NCTrashListCell.xib in Resources */, F700510122DF63AC003A3356 /* NCShare.storyboard in Resources */, F787704F22E7019900F287A9 /* NCShareLinkCell.xib in Resources */, + F70A58C024D0545100DED00D /* NCCapabilitiesViewController.storyboard in Resources */, F749C10D23C4A5340027D966 /* NCIntro.storyboard in Resources */, F747BA1F22354D2000971601 /* NCCreateFormUploadVoiceNote.storyboard in Resources */, F7B2DEF11F976859007CF4D2 /* english.txt in Resources */, @@ -1980,11 +1974,11 @@ F7E09CE323E3088000FB3E9E /* NCMainRefreshControl.swift in Sources */, F77B0DF41D118A16002130FE /* CCMain.m in Sources */, F7AE00F8230E81CB007ACF8A /* NCBrowserWeb.swift in Sources */, + F70A58BE24D0349500DED00D /* NCCapabilitiesViewController.swift in Sources */, 370D26AF248A3D7A00121797 /* NCImageCellProtocol.swift in Sources */, F7E9C41B20F4CA870040CF18 /* CCTransfers.m in Sources */, 37C83A0F24532BA600618A3B /* CCMain+Swift.swift in Sources */, F77B0DF51D118A16002130FE /* CCUtility.m in Sources */, - F7B0C0CD1EE7E7750033AC24 /* CCSynchronize.m in Sources */, F710D1FE24057E5E00A6033D /* NCActionSheetHeader.swift in Sources */, F790110E21415BF600D7B136 /* NCViewerRichdocument.swift in Sources */, 370D26AD248A3BB800121797 /* CCCellMainTransfer.swift in Sources */, @@ -2213,7 +2207,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 18; + CURRENT_PROJECT_VERSION = 16; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 6JLRKY9ZV7; FRAMEWORK_SEARCH_PATHS = ( @@ -2232,7 +2226,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**"; - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.0.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; OTHER_LDFLAGS = "-ObjC"; @@ -2264,7 +2258,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 18; + CURRENT_PROJECT_VERSION = 16; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 6JLRKY9ZV7; FRAMEWORK_SEARCH_PATHS = ( @@ -2283,7 +2277,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**"; - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.0.2; MTL_FAST_MATH = YES; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.Notification-Service-Extension"; @@ -2307,7 +2301,7 @@ CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/Share.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 18; + CURRENT_PROJECT_VERSION = 16; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 6JLRKY9ZV7; FRAMEWORK_SEARCH_PATHS = ( @@ -2326,7 +2320,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**"; - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.0.2; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.Nextcloud.Share; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2351,7 +2345,7 @@ CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/Share.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 18; + CURRENT_PROJECT_VERSION = 16; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 6JLRKY9ZV7; FRAMEWORK_SEARCH_PATHS = ( @@ -2370,7 +2364,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**"; - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.0.2; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = it.twsweb.Nextcloud.Share; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2401,7 +2395,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 18; + CURRENT_PROJECT_VERSION = 16; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 6JLRKY9ZV7; FRAMEWORK_SEARCH_PATHS = ( @@ -2420,7 +2414,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**"; - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.0.2; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.File-Provider-Extension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2451,7 +2445,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 18; + CURRENT_PROJECT_VERSION = 16; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 6JLRKY9ZV7; FRAMEWORK_SEARCH_PATHS = ( @@ -2470,7 +2464,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LIBRARY_SEARCH_PATHS = "\"Libraries external\"/**"; - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.0.2; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.Nextcloud.File-Provider-Extension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -2493,7 +2487,7 @@ CODE_SIGN_ENTITLEMENTS = iOSClient/Brand/iOSClient.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 18; + CURRENT_PROJECT_VERSION = 16; DEVELOPMENT_TEAM = 6JLRKY9ZV7; ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -2509,7 +2503,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LIBRARY_SEARCH_PATHS = ""; - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.0.2; OTHER_LDFLAGS = "-ObjC"; OTHER_SWIFT_FLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.$(PRODUCT_NAME:rfc1034identifier)"; @@ -2538,7 +2532,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 18; + CURRENT_PROJECT_VERSION = 16; DEVELOPMENT_TEAM = 6JLRKY9ZV7; ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -2553,7 +2547,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LIBRARY_SEARCH_PATHS = ""; - MARKETING_VERSION = 3.0.1; + MARKETING_VERSION = 3.0.2; OTHER_LDFLAGS = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = "it.twsweb.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/Share/NCSelectDestination.m b/Share/NCSelectDestination.m index aca80f91a..9e9fe89ae 100644 --- a/Share/NCSelectDestination.m +++ b/Share/NCSelectDestination.m @@ -165,7 +165,7 @@ - (void)readFolder { - [[NCNetworking shared] readFolderWithServerUrl:_serverUrl account:activeAccount completion:^(NSString *account, tableMetadata *metadataFolder, NSArray *metadatas, NSInteger errorCode, NSString *errorDescription) { + [[NCNetworking shared] readFolderWithServerUrl:_serverUrl account:activeAccount completion:^(NSString *account, tableMetadata *metadataFolder, NSArray *metadatas, NSArray *metadatasChanged, NSInteger errorCode, NSString *errorDescription) { if (errorCode == 0) { self.move.enabled = true; @@ -225,7 +225,7 @@ } } - NSArray *result = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:predicateDataSource page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO]; + NSArray *result = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:predicateDataSource page:0 limit:0 sorted:@"fileName" ascending:NO]; if (result) return [result count]; @@ -284,7 +284,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataAtIndexWithPredicate:predicateDataSource sorted:@"fileName" ascending:YES index:indexPath.row]; + tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataAtIndexWithPredicate:predicateDataSource sorted:@"fileName" ascending:YES index:indexPath.row ]; if (metadata.directory) { diff --git a/Share/ShareViewController.h b/Share/ShareViewController.h index f585e78f5..ff3119b6d 100644 --- a/Share/ShareViewController.h +++ b/Share/ShareViewController.h @@ -32,6 +32,7 @@ @interface ShareViewController : UIViewController <UITableViewDelegate, MBProgressHUDDelegate, NCSelectDestinationDelegate, UITextFieldDelegate> @property (nonatomic, strong) NSString *activeAccount; +@property (nonatomic, strong) NSString *activeUrl; @property (nonatomic, strong) NSString *serverUrl; @property (nonatomic, retain) NSMutableArray *filesName; diff --git a/Share/ShareViewController.m b/Share/ShareViewController.m index bc98a621c..83ba91f5e 100644 --- a/Share/ShareViewController.m +++ b/Share/ShareViewController.m @@ -68,6 +68,7 @@ [[NCCommunicationCommon shared] setupWithAccount:tableAccount.account user:tableAccount.user userId:tableAccount.userID password:[CCUtility getPassword:tableAccount.account] url:tableAccount.url userAgent:[CCUtility getUserAgent] capabilitiesGroup:[NCBrandOptions sharedInstance].capabilitiesGroups webDavRoot:webDavRoot davRoot:nil nextcloudVersion:serverVersionMajor delegate:[NCNetworking shared]]; _activeAccount = tableAccount.account; + _activeUrl = tableAccount.url; if ([_activeAccount isEqualToString:[CCUtility getActiveAccountExt]]) { @@ -281,15 +282,15 @@ [CCUtility copyFileAtPath:fileNameLocal toPath:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileNameForUpload]]; - tableMetadata *metadata = [[NCManageDatabase sharedInstance] createMetadataWithAccount:self.activeAccount fileName:fileNameForUpload ocId:ocId serverUrl:self.serverUrl url:@"" contentType:@""]; + tableMetadata *metadata = [[NCManageDatabase sharedInstance] createMetadataWithAccount:self.activeAccount fileName:fileNameForUpload ocId:ocId serverUrl:self.serverUrl urlBase:self.activeUrl url:@"" contentType:@""]; metadata.date = date; metadata.etag = etag; metadata.serverUrl = self.serverUrl; metadata.size = size; - metadata = [[NCManageDatabase sharedInstance] addMetadata:metadata]; - (void)[[NCManageDatabase sharedInstance] addLocalFileWithMetadata:metadata]; + [[NCManageDatabase sharedInstance] addMetadata:metadata]; + [[NCManageDatabase sharedInstance] addLocalFileWithMetadata:metadata]; [self.shareTable performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; [self performSelector:@selector(selectPost) withObject:nil]; diff --git a/iOSClient/Activity/NCActivity.swift b/iOSClient/Activity/NCActivity.swift index 4e229cba9..34537be44 100644 --- a/iOSClient/Activity/NCActivity.swift +++ b/iOSClient/Activity/NCActivity.swift @@ -361,7 +361,7 @@ extension activityTableViewCell: UICollectionViewDelegate { viewController.path = result.filePath (responder as? UIViewController)!.navigationController?.pushViewController(viewController, animated: true) } else { - NCContentPresenter.shared.messageNotification("_error_", description: "_trash_file_not_found_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0) + NCContentPresenter.shared.messageNotification("_error_", description: "_trash_file_not_found_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError)) } } } @@ -423,9 +423,8 @@ extension activityTableViewCell: UICollectionViewDelegate { CCUtility.moveFile(atPath: atPath, toPath: toPath) - if let metadata = NCManageDatabase.sharedInstance.addMetadata(metadata!) { - self.appDelegate.activeMain.performSegue(withIdentifier: "segueDetail", sender: metadata) - } + NCManageDatabase.sharedInstance.addMetadata(metadata!) + self.appDelegate.activeMain.performSegue(withIdentifier: "segueDetail", sender: metadata) } } diff --git a/iOSClient/AppDelegate.m b/iOSClient/AppDelegate.m index 8e84d52c1..236eceea2 100644 --- a/iOSClient/AppDelegate.m +++ b/iOSClient/AppDelegate.m @@ -23,7 +23,6 @@ #import "AppDelegate.h" #import "CCGraphics.h" -#import "CCSynchronize.h" #import "CCMain.h" #import "NCBridgeSwift.h" #import "NCAutoUpload.h" @@ -222,6 +221,8 @@ [self.window.rootViewController presentViewController:vc animated:YES completion:nil]; } #endif + + //[[NCNetworking shared] verifyUploadZombie]; } // @@ -712,7 +713,7 @@ if (self.activeAccount.length == 0 || self.maintenanceMode) return; NSInteger counterDownload = [[NCOperationQueue shared] downloadCount]; - NSInteger counterUpload = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"status == %d OR status == %d OR status == %d", k_metadataStatusWaitUpload, k_metadataStatusInUpload, k_metadataStatusUploading] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:YES].count; + NSInteger counterUpload = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"status == %d OR status == %d OR status == %d", k_metadataStatusWaitUpload, k_metadataStatusInUpload, k_metadataStatusUploading] page:0 limit:0 sorted:@"fileName" ascending:NO].count; NSInteger total = counterDownload + counterUpload; [UIApplication sharedApplication].applicationIconBadgeNumber = total; @@ -839,7 +840,7 @@ UIViewController *vc = _activeMain.splitViewController.viewControllers[0]; [self showMenuInViewController: vc]; } else { - [[NCContentPresenter shared] messageNotification:@"_warning_" description:@"_no_permission_add_file_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0]; + [[NCContentPresenter shared] messageNotification:@"_warning_" description:@"_no_permission_add_file_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:false]; } } @@ -894,7 +895,7 @@ if (isTooLight) { NCBrandColor.sharedInstance.brandElement = [NCBrandColor.sharedInstance.brandElement darkerBy:10]; } else if (isTooDark) { - NCBrandColor.sharedInstance.brandElement = [NCBrandColor.sharedInstance.brandElement lighterBy:15]; + NCBrandColor.sharedInstance.brandElement = [NCBrandColor.sharedInstance.brandElement lighterBy:25]; } } else { @@ -905,7 +906,7 @@ if (isTooLight) { NCBrandColor.sharedInstance.brandElement = [NCBrandColor.sharedInstance.customer darkerBy:10]; } else if (isTooDark) { - NCBrandColor.sharedInstance.brandElement = [NCBrandColor.sharedInstance.customer lighterBy:15]; + NCBrandColor.sharedInstance.brandElement = [NCBrandColor.sharedInstance.customer lighterBy:25]; } else { NCBrandColor.sharedInstance.brandElement = NCBrandColor.sharedInstance.customer; } @@ -984,7 +985,7 @@ // after 20 sec dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 20 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - NSInteger results = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session != ''"] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:YES].count; + NSInteger results = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session != ''"] page:0 limit:0 sorted:@"fileName" ascending:NO].count; if (results > 0) { completionHandler(UIBackgroundFetchResultNewData); @@ -1115,7 +1116,7 @@ // Push NSString *fileName = [[path stringByDeletingLastPathComponent] lastPathComponent]; NSString *serverUrl = [CCUtility deletingLastPathComponentFromServerUrl:[NSString stringWithFormat:@"%@%@/%@", matchedAccount.url, k_webDAV, [path stringByDeletingLastPathComponent]]]; - tableMetadata *metadata = [[NCManageDatabase sharedInstance] createMetadataWithAccount:matchedAccount.account fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl url:@"" contentType:@""]; + tableMetadata *metadata = [[NCManageDatabase sharedInstance] createMetadataWithAccount:matchedAccount.account fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl urlBase: @"" url:@"" contentType:@""]; [self.activeMain performSegueDirectoryWithMetadata:metadata blinkFileNamePath:fileNamePath]; } else { @@ -1128,9 +1129,6 @@ } }); }); - - - } } } diff --git a/iOSClient/AutoUpload/NCAutoUpload.m b/iOSClient/AutoUpload/NCAutoUpload.m index 3a296e10f..7617363d9 100644 --- a/iOSClient/AutoUpload/NCAutoUpload.m +++ b/iOSClient/AutoUpload/NCAutoUpload.m @@ -333,10 +333,15 @@ - (void)uploadAssetsNewAndFull:(NSString *)selector { - if (!appDelegate.activeAccount || appDelegate.maintenanceMode) + if (!appDelegate.activeAccount || appDelegate.maintenanceMode) { return; + } tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountActive]; + if (tableAccount == nil) { + return; + } + NSMutableArray *metadataFull = [NSMutableArray new]; NSString *autoUploadPath = [[NCManageDatabase sharedInstance] getAccountAutoUploadPath:appDelegate.activeUrl]; NSString *serverUrl; @@ -394,10 +399,10 @@ else serverUrl = autoUploadPath; - tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND fileNameView == %@", appDelegate.activeAccount, serverUrl, fileName] freeze:true]; + tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND fileNameView == %@", appDelegate.activeAccount, serverUrl, fileName]]; if (!metadata) { - tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl url:@"" contentType:@""]; + tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl urlBase:appDelegate.activeUrl url:@"" contentType:@""]; metadataForUpload.assetLocalIdentifier = asset.localIdentifier; metadataForUpload.session = session; @@ -423,7 +428,7 @@ if (url != nil) { unsigned long long fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:url.path error:nil] fileSize]; - tableMetadata *metadataMOVForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileNameMove ocId:ocId serverUrl:serverUrl url:@"" contentType:@""]; + tableMetadata *metadataMOVForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileNameMove ocId:ocId serverUrl:serverUrl urlBase:appDelegate.activeUrl url:@"" contentType:@""]; metadataMOVForUpload.session = session; metadataMOVForUpload.sessionSelector = selector; diff --git a/iOSClient/CCGlobal.h b/iOSClient/CCGlobal.h index a542b5280..8defa10e2 100644 --- a/iOSClient/CCGlobal.h +++ b/iOSClient/CCGlobal.h @@ -158,12 +158,21 @@ #define k_maxHTTPCache 10737418240 // 10GB // Error -#define k_CCErrorInternalError -9999 +#define k_CCErrorInternalError -99999 +#define k_CCErrorFileNotSaved -99998 +#define k_CCErrorDecodeMetadata -99997 +#define k_CCErrorE2EENotEnabled -99996 +#define k_CCErrorE2EENotMove -99995 +#define k_CCErrorOffline -99994 +#define k_CCErrorCharactersForbidden -99993 +#define k_CCErrorCreationFile -99992 + // Search #define k_minCharsSearch 2 // Selector +#define selectorSynchronize @"synchronize" #define selectorDownloadSynchronize @"downloadSynchronize" #define selectorLoadFileView @"loadFileView" #define selectorLoadFileViewFavorite @"loadFileViewFavorite" @@ -172,10 +181,6 @@ #define selectorLoadOffline @"loadOffline" #define selectorOpenIn @"openIn" #define selectorOpenInDetail @"openInDetail" -#define selectorReadFile @"readFile" -#define selectorReadFileWithDownload @"readFileWithDownload" -#define selectorReadFolder @"readFolder" -#define selectorReadFolderWithDownload @"readFolderWithDownload" #define selectorSave @"save" #define selectorUploadAutoUpload @"uploadAutoUpload" #define selectorUploadAutoUploadAll @"uploadAutoUploadAll" @@ -233,6 +238,7 @@ // E2EE #define k_max_filesize_E2EE 524288000 // 500 MB +#define k_E2EE_API @"1.1" // Flow Version #define k_flow_version_available 12 diff --git a/iOSClient/Database/NCManageDatabase.swift b/iOSClient/Database/NCManageDatabase.swift index 9e676402a..010af0508 100644 --- a/iOSClient/Database/NCManageDatabase.swift +++ b/iOSClient/Database/NCManageDatabase.swift @@ -47,7 +47,7 @@ class NCManageDatabase: NSObject { let config = Realm.Configuration( fileURL: dirGroup?.appendingPathComponent("\(k_appDatabaseNextcloud)/\(k_databaseDefault)"), schemaVersion: UInt64(k_databaseSchemaVersion), - objectTypes: [tableMetadata.self, tableLocalFile.self, tableDirectory.self, tableTag.self, tableAccount.self, tableCapabilities.self] + objectTypes: [tableMetadata.self, tableLocalFile.self, tableDirectory.self, tableTag.self, tableAccount.self, tableCapabilities.self, tableE2eEncryption.self] ) Realm.Configuration.defaultConfiguration = config @@ -131,7 +131,7 @@ class NCManageDatabase: NSObject { if let databaseFilePath = databaseFilePath { do { #if !EXTENSION - NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: TimeInterval(k_dismissAfterSecondLong), type: NCContentPresenter.messageType.info, errorCode: 0) + NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: TimeInterval(k_dismissAfterSecondLong), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true) #endif try FileManager.default.removeItem(at: databaseFilePath) } catch {} @@ -153,7 +153,7 @@ class NCManageDatabase: NSObject { if let databaseFilePath = databaseFilePath { do { #if !EXTENSION - NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: TimeInterval(k_dismissAfterSecondLong), type: NCContentPresenter.messageType.info, errorCode: 0) + NCContentPresenter.shared.messageNotification("_error_", description: "_database_corrupt_", delay: TimeInterval(k_dismissAfterSecondLong), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true) #endif try FileManager.default.removeItem(at: databaseFilePath) } catch {} @@ -872,6 +872,23 @@ class NCManageDatabase: NSObject { } } + @objc func getCapabilities(account: String) -> String? { + + let realm = try! Realm() + realm.refresh() + + guard let result = realm.objects(tableCapabilities.self).filter("account == %@", account).first else { + return nil + } + guard let jsondata = result.jsondata else { + return nil + } + + let json = JSON(jsondata) + + return json.rawString() + } + @objc func getCapabilitiesServerString(account: String, elements: Array<String>) -> String? { let realm = try! Realm() @@ -994,7 +1011,7 @@ class NCManageDatabase: NSObject { let results = realm.objects(tableComments.self).filter("account == %@ AND objectId == %@", account, objectId).sorted(byKeyPath: "creationDateTime", ascending: false) - return Array(results.map { tableComments.init(value:$0) }) + return Array(results.map { $0.freeze() }) } //MARK: - @@ -1061,7 +1078,7 @@ class NCManageDatabase: NSObject { let results = realm.objects(tableDirectEditingCreators.self).filter("account == %@", account) if (results.count > 0) { - return Array(results.map { tableDirectEditingCreators.init(value:$0) }) + return Array(results.map { $0.freeze() }) } else { return nil } @@ -1074,7 +1091,7 @@ class NCManageDatabase: NSObject { let results = realm.objects(tableDirectEditingCreators.self).filter(predicate) if (results.count > 0) { - return Array(results.map { tableDirectEditingCreators.init(value:$0) }) + return Array(results.map { $0.freeze() }) } else { return nil } @@ -1086,7 +1103,7 @@ class NCManageDatabase: NSObject { let results = realm.objects(tableDirectEditingEditors.self).filter("account == %@", account) if (results.count > 0) { - return Array(results.map { tableDirectEditingEditors.init(value:$0) }) + return Array(results.map { $0.freeze() }) } else { return nil } @@ -1099,8 +1116,7 @@ class NCManageDatabase: NSObject { return tableDirectory.init(value: directory) } - @discardableResult - @objc func addDirectory(encrypted: Bool, favorite: Bool, ocId: String, fileId: String, etag: String?, permissions: String?, serverUrl: String, richWorkspace: String?, account: String) -> tableDirectory? { + @objc func addDirectory(encrypted: Bool, favorite: Bool, ocId: String, fileId: String, etag: String?, permissions: String?, serverUrl: String, richWorkspace: String?, account: String) { let realm = try! Realm() realm.beginWrite() @@ -1134,10 +1150,7 @@ class NCManageDatabase: NSObject { try realm.commitWrite() } catch let error { print("[LOG] Could not write to database: ", error) - return nil } - - return tableDirectory.init(value: addObject) } @objc func deleteDirectoryAndSubDirectory(serverUrl: String, account: String) { @@ -1572,8 +1585,7 @@ class NCManageDatabase: NSObject { return tableLocalFile.init(value: localFile) } - @discardableResult - @objc func addLocalFile(metadata: tableMetadata) -> tableLocalFile? { + @objc func addLocalFile(metadata: tableMetadata) { let realm = try! Realm() let addObject = tableLocalFile() @@ -1595,10 +1607,7 @@ class NCManageDatabase: NSObject { } } catch let error { print("[LOG] Could not write to database: ", error) - return nil } - - return tableLocalFile.init(value: addObject) } @objc func deleteLocalFile(predicate: NSPredicate) { @@ -1660,22 +1669,17 @@ class NCManageDatabase: NSObject { guard let result = realm.objects(tableLocalFile.self).filter(predicate).first else { return nil } - - return tableLocalFile.init(value: result) + + return result.freeze() } - @objc func getTableLocalFiles(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableLocalFile]? { + @objc func getTableLocalFiles(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableLocalFile] { let realm = try! Realm() realm.refresh() let results = realm.objects(tableLocalFile.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending) - - if (results.count > 0) { - return Array(results.map { tableLocalFile.init(value:$0) }) - } else { - return nil - } + return Array(results.map { $0.freeze() }) } @objc func setLocalFile(ocId: String, offline: Bool) { @@ -1795,7 +1799,7 @@ class NCManageDatabase: NSObject { completion(metadataFolder, metadataFolders, metadatas) } - @objc func createMetadata(account: String, fileName: String, ocId: String, serverUrl: String, url: String, contentType: String) -> tableMetadata { + @objc func createMetadata(account: String, fileName: String, ocId: String, serverUrl: String, urlBase: String, url: String, contentType: String) -> tableMetadata { let metadata = tableMetadata() let results = NCCommunicationCommon.shared.getInternalContenType(fileName: fileName, contentType: contentType, directory: false) @@ -1813,12 +1817,12 @@ class NCManageDatabase: NSObject { metadata.typeFile = results.typeFile metadata.uploadDate = Date() as NSDate metadata.url = url + metadata.urlBase = urlBase return metadata } - @discardableResult - @objc func addMetadata(_ metadata: tableMetadata) -> tableMetadata? { + @objc func addMetadata(_ metadata: tableMetadata) { let realm = try! Realm() @@ -1828,35 +1832,24 @@ class NCManageDatabase: NSObject { } } catch let error { print("[LOG] Could not write to database: ", error) - return nil } - - return tableMetadata.init(value: metadata) } - @discardableResult - @objc func addMetadatas(_ metadatas: [tableMetadata]) -> [tableMetadata]? { + @objc func addMetadatas(_ metadatas: [tableMetadata]) { - var directoryToClearDate: [String: String] = [:] - let realm = try! Realm() do { try realm.write { for metadata in metadatas { - directoryToClearDate[metadata.serverUrl] = metadata.account realm.add(metadata, update: .all) } } } catch let error { print("[LOG] Could not write to database: ", error) - return nil } - - - return Array(metadatas.map { tableMetadata.init(value:$0) }) } - + @objc func addMetadatas(files: [NCCommunicationFile]?, account: String) { guard let files = files else { return } @@ -1915,19 +1908,12 @@ class NCManageDatabase: NSObject { } @objc func deleteMetadata(predicate: NSPredicate) { - - var directoryToClearDate: [String: String] = [:] - + let realm = try! Realm() realm.beginWrite() let results = realm.objects(tableMetadata.self).filter(predicate) - - for result in results { - directoryToClearDate[result.serverUrl] = result.account - } - realm.delete(results) do { @@ -1938,8 +1924,7 @@ class NCManageDatabase: NSObject { } } - @discardableResult - @objc func moveMetadata(ocId: String, serverUrlTo: String) -> tableMetadata? { + @objc func moveMetadata(ocId: String, serverUrlTo: String) { var result: tableMetadata? let realm = try! Realm() @@ -1953,14 +1938,7 @@ class NCManageDatabase: NSObject { } } catch let error { print("[LOG] Could not write to database: ", error) - return nil } - - if result == nil { - return nil - } - - return tableMetadata.init(value: result!) } @objc func addMetadataServerUrl(ocId: String, serverUrl: String) { @@ -1980,8 +1958,7 @@ class NCManageDatabase: NSObject { } } - @discardableResult - @objc func renameMetadata(fileNameTo: String, ocId: String) -> tableMetadata? { + @objc func renameMetadata(fileNameTo: String, ocId: String) { var result: tableMetadata? let realm = try! Realm() @@ -1996,30 +1973,60 @@ class NCManageDatabase: NSObject { } } catch let error { print("[LOG] Could not write to database: ", error) - return nil - } - - if result == nil { - return nil } - - return tableMetadata.init(value: result!) } - - @objc func updateMetadata(_ metadata: tableMetadata) -> tableMetadata? { + + @discardableResult + @objc func updateMetadatas(_ metadatas: [tableMetadata], metadatasResult: [tableMetadata] ,withVerifyLocal local: Bool = false) -> [tableMetadata] { let realm = try! Realm() - + var ocIdsUdated : [String] = [] + var metadatasUdated : [tableMetadata] = [] + do { try realm.write { - realm.add(metadata, update: .all) + // DELETE + for metadataResult in metadatasResult { + if metadatas.firstIndex(where: { $0.ocId == metadataResult.ocId }) == nil { + if let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "ocId == %@", metadataResult.ocId)).first { + realm.delete(result) + } + } + } + // UPDATE/NEW + for metadata in metadatas { + var updated = false + if let result = metadatasResult.first(where: { $0.ocId == metadata.ocId }) { + // update + if result.status == k_metadataStatusNormal && result.etag != metadata.etag { + ocIdsUdated.append(metadata.ocId) + realm.add(metadata, update: .all) + updated = true + } + } else { + // new + ocIdsUdated.append(metadata.ocId) + realm.add(metadata, update: .all) + updated = true + } + if local && !updated { + if realm.objects(tableLocalFile.self).filter(NSPredicate(format: "ocId == %@", metadata.ocId)).first == nil { + ocIdsUdated.append(metadata.ocId) + } + } + } } } catch let error { print("[LOG] Could not write to database: ", error) - return nil } - - return tableMetadata.init(value: metadata) + + for ocId in ocIdsUdated { + if let result = realm.objects(tableMetadata.self).filter(NSPredicate(format: "ocId == %@", ocId)).first { + metadatasUdated.append(result.freeze()) + } + } + + return metadatasUdated } func setMetadataSession(ocId: String, session: String? = nil, sessionError: String? = nil, sessionSelector: String? = nil, sessionTaskIdentifier: Int? = nil, status: Int? = nil, etag: String? = nil, setFavorite: Bool = false) { @@ -2128,41 +2135,19 @@ class NCManageDatabase: NSObject { return nil } - return tableMetadata.init(value: result) + return result.freeze() } - @objc func getMetadata(predicate: NSPredicate, freeze: Bool) -> tableMetadata? { + @objc func getMetadata(predicate: NSPredicate, sorted: String, ascending: Bool) -> tableMetadata? { let realm = try! Realm() realm.refresh() - guard let result = realm.objects(tableMetadata.self).filter(predicate).first else { - return nil - } - - if freeze { - return result.freeze() - } else { - return result - } - } - - @objc func getMetadata(predicate: NSPredicate, sorted: String, ascending: Bool, freeze: Bool = false) -> tableMetadata? { - - let realm = try! Realm() - realm.refresh() - - let results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending) - - if (results.count > 0) { - if freeze { - return results[0].freeze() - } else { - return tableMetadata.init(value: results[0]) - } - } else { + guard let result = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending).first else { return nil } + + return result.freeze() } @objc func getMetadatasViewer(predicate: NSPredicate, sorted: String, ascending: Bool) -> [tableMetadata]? { @@ -2198,28 +2183,25 @@ class NCManageDatabase: NSObject { } if (finals.count > 0) { - return Array(finals.map { tableMetadata.init(value:$0) }) + return Array(finals.map { tableMetadata.init(value:$0.freeze()) }) } else { return nil } } - @objc func getMetadatas(predicate: NSPredicate, page: Int = 0, limit: Int = 0, sorted: String = "fileName", ascending: Bool = false, freeze: Bool = false) -> [tableMetadata]? { + @objc func getMetadatas(predicate: NSPredicate, page: Int = 0, limit: Int = 0, sorted: String = "fileName", ascending: Bool = false) -> [tableMetadata] { let realm = try! Realm() realm.refresh() + var metadatas: [tableMetadata] = [] let results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending) if results.count > 0 { if page == 0 || limit == 0 { - if freeze { - return Array(results.freeze()) - } else { - return Array(results.map { tableMetadata.init(value:$0) }) - } + return Array(results.freeze()) } else { - var metadatas: [tableMetadata] = [] + let nFrom = (page - 1) * limit let nTo = nFrom + (limit - 1) @@ -2227,17 +2209,11 @@ class NCManageDatabase: NSObject { if n == results.count { break } - if freeze { - metadatas.append(results[n].freeze()) - } else { - metadatas.append(tableMetadata.init(value: results[n])) - } + metadatas.append(results[n].freeze()) } - return metadatas } - } else { - return nil } + return metadatas } @objc func getMetadataAtIndex(predicate: NSPredicate, sorted: String, ascending: Bool, index: Int) -> tableMetadata? { @@ -2248,13 +2224,13 @@ class NCManageDatabase: NSObject { let results = realm.objects(tableMetadata.self).filter(predicate).sorted(byKeyPath: sorted, ascending: ascending) if (results.count > 0 && results.count > index) { - return tableMetadata.init(value: results[index]) + return tableMetadata.init(value: results[index].freeze()) } else { return nil } } - @objc func getMetadataInSessionFromFileName(_ fileName: String, serverUrl: String, taskIdentifier: Int, freeze: Bool) -> tableMetadata? { + @objc func getMetadataInSessionFromFileName(_ fileName: String, serverUrl: String, taskIdentifier: Int) -> tableMetadata? { let realm = try! Realm() realm.refresh() @@ -2263,11 +2239,7 @@ class NCManageDatabase: NSObject { return nil } - if freeze { - return result.freeze() - } else { - return tableMetadata.init(value: result) - } + return result.freeze() } @objc func getTableMetadatasDirectoryFavoriteIdentifierRank(account: String) -> [String: NSNumber] { @@ -2381,10 +2353,10 @@ class NCManageDatabase: NSObject { return nil } - return tableMetadata.init(value: result) + return result.freeze() } - @objc func getMetadatasMedia(predicate: NSPredicate, sort: String, ascending: Bool = false, completion: @escaping (_ metadatas: [tableMetadata])->()) { + func getMetadatasMedia(predicate: NSPredicate, sort: String, ascending: Bool = false, completion: @escaping (_ metadatas: [tableMetadata])->()) { DispatchQueue.global().async { autoreleasepool { diff --git a/iOSClient/Favorites/CCFavorites.h b/iOSClient/Favorites/CCFavorites.h index cc0e94898..a6e0525cb 100644 --- a/iOSClient/Favorites/CCFavorites.h +++ b/iOSClient/Favorites/CCFavorites.h @@ -41,7 +41,6 @@ @property (nonatomic, strong) NSString *titleViewControl; - (void)shouldPerformSegue:(tableMetadata *)metadata selector:(NSString *)selector; -- (void)listingFavorites; - (void)actionDelete:(NSIndexPath *)indexPath; @end diff --git a/iOSClient/Favorites/CCFavorites.m b/iOSClient/Favorites/CCFavorites.m index b7c29973f..c6740bf49 100644 --- a/iOSClient/Favorites/CCFavorites.m +++ b/iOSClient/Favorites/CCFavorites.m @@ -23,7 +23,6 @@ #import "CCFavorites.h" #import "AppDelegate.h" -#import "CCSynchronize.h" #import "NCBridgeSwift.h" @@ -98,6 +97,13 @@ [self changeTheming]; } +- (void)viewWillAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + + [self reloadDatasource]; +} + - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; @@ -105,10 +111,10 @@ // Active Main appDelegate.activeFavorites = self; - [self reloadDatasource]; - - if (self.serverUrl == nil) { - [self listingFavorites]; + if (self.serverUrl == nil && appDelegate.activeAccount.length > 0) { + [[NCNetworking shared] listingFavoritescompletionWithCompletion:^(NSString *account, NSArray* metadatas, NSInteger errorCode, NSString *errorDescription) { + [self reloadDatasource]; + }]; } } @@ -170,65 +176,6 @@ return [[NSAttributedString alloc] initWithString:text attributes:attributes]; } -#pragma -------------------------------------------------------------------------------------------- -#pragma mark ===== listingFavorites ===== -#pragma-------------------------------------------------------------------------------------------- - -- (void)listingFavorites -{ - // test - if (appDelegate.activeAccount.length == 0) - return; - - [[NCCommunication shared] listingFavoritesWithShowHiddenFiles:[CCUtility getShowHiddenFiles] customUserAgent:nil addCustomHeaders:nil completionHandler:^(NSString *account, NSArray *files, NSInteger errorCode, NSString *errorMessage) { - if (errorCode == 0 && [account isEqualToString:appDelegate.activeAccount] && files != nil) { - [[NCManageDatabase sharedInstance] convertNCCommunicationFilesToMetadatas:files useMetadataFolder:false account:account completion:^(tableMetadata *metadataFolder, NSArray<tableMetadata *> *metadatasFolder, NSArray<tableMetadata *> *metadatas) { - NSString *father = @""; - NSMutableArray *filesOcId = [NSMutableArray new]; - - for (tableMetadata *metadata in metadatas) { - // insert for test NOT favorite - [filesOcId addObject:metadata.ocId]; - NSString *serverUrl = metadata.serverUrl; - NSString *serverUrlSon = [CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileName]; - if (![serverUrlSon containsString:father]) { - if (metadata.directory) { - if ([CCUtility getFavoriteOffline]) - [[CCSynchronize sharedSynchronize] readFolder:[CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileName] selector:selectorReadFolderWithDownload account:account]; - else - [[CCSynchronize sharedSynchronize] readFolder:[CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileName] selector:selectorReadFolder account:account]; - } else { - if ([CCUtility getFavoriteOffline]) - [[CCSynchronize sharedSynchronize] readFile:metadata.ocId fileName:metadata.fileName serverUrl:serverUrl selector:selectorReadFileWithDownload account:account]; - else - [[CCSynchronize sharedSynchronize] readFile:metadata.ocId fileName:metadata.fileName serverUrl:serverUrl selector:selectorReadFile account:account]; - } - father = serverUrlSon; - } - tableMetadata *metadataFavorite = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", metadata.ocId]]; - if (metadataFavorite == nil) { - [[NCManageDatabase sharedInstance] addMetadata:metadata]; - } else if (!metadataFavorite.favorite) { - [[NCManageDatabase sharedInstance] setMetadataFavoriteWithOcId:metadata.ocId favorite:true]; - } - } - - // Verify remove favorite - NSArray *allRecordFavorite = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND favorite == true", account] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO]; - for (tableMetadata *metadata in allRecordFavorite) - if (![filesOcId containsObject:metadata.ocId]) - [[NCManageDatabase sharedInstance] setMetadataFavoriteWithOcId:metadata.ocId favorite:NO]; - - [self reloadDatasource]; - }]; - } else if (errorCode != 0) { - [[NCContentPresenter shared] messageNotification:@"_error_" description:errorMessage delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode]; - } else { - NSLog(@"[LOG] It has been changed user during networking process, error."); - } - }]; -} - - (void)tapActionComment:(UITapGestureRecognizer *)tapGesture { CGPoint location = [tapGesture locationInView:self.tableView]; @@ -431,11 +378,11 @@ if (!_serverUrl) { - recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND favorite == true", appDelegate.activeAccount] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO]; + recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND favorite == true", appDelegate.activeAccount] page:0 limit:0 sorted:@"fileName" ascending:NO]; } else { - recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.activeAccount, self.serverUrl] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO]; + recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.activeAccount, self.serverUrl] page:0 limit:0 sorted:@"fileName" ascending:NO]; } sectionDataSource = [CCSectionMetadata creataDataSourseSectionMetadata:recordsTableMetadata listProgressMetadata:nil groupByField:nil filterTypeFileImage:NO filterTypeFileVideo:NO filterLivePhoto:YES sorted:sorted ascending:[CCUtility getAscendingSettings] activeAccount:appDelegate.activeAccount]; @@ -577,7 +524,7 @@ if (tableDirectory.e2eEncrypted && ![CCUtility isEndToEndEnabled:appDelegate.activeAccount]) { - [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0]; + [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:false]; } else { @@ -590,7 +537,7 @@ if (NCCommunication.shared.isNetworkReachable) { [self shouldPerformSegue:self.metadata selector:@""]; } else { - [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0]; + [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:false]; } } else if ([self.metadata.typeFile isEqualToString: k_metadataTypeFile_document] && [[NCUtility sharedInstance] isRichDocument:self.metadata]) { @@ -598,7 +545,7 @@ if (NCCommunication.shared.isNetworkReachable) { [self shouldPerformSegue:self.metadata selector:@""]; } else { - [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0]; + [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorInternalError forced:false]; } } else { diff --git a/iOSClient/Images.xcassets/avatarBN.imageset/Contents.json b/iOSClient/Images.xcassets/avatarBN.imageset/Contents.json index 9292dd7b6..6f494e105 100644 --- a/iOSClient/Images.xcassets/avatarBN.imageset/Contents.json +++ b/iOSClient/Images.xcassets/avatarBN.imageset/Contents.json @@ -1,23 +1,15 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "avatarBN.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "avatarBN@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "avatarBN@3x.png", - "scale" : "3x" + "filename" : "avatarBN.pdf", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true } -}
\ No newline at end of file +} diff --git a/iOSClient/Images.xcassets/avatarBN.imageset/avatarBN.pdf b/iOSClient/Images.xcassets/avatarBN.imageset/avatarBN.pdf Binary files differnew file mode 100644 index 000000000..1aa892501 --- /dev/null +++ b/iOSClient/Images.xcassets/avatarBN.imageset/avatarBN.pdf diff --git a/iOSClient/Images.xcassets/avatarBN.imageset/avatarBN.png b/iOSClient/Images.xcassets/avatarBN.imageset/avatarBN.png Binary files differdeleted file mode 100644 index c6f99224e..000000000 --- a/iOSClient/Images.xcassets/avatarBN.imageset/avatarBN.png +++ /dev/null diff --git a/iOSClient/Images.xcassets/avatarBN.imageset/avatarBN@2x.png b/iOSClient/Images.xcassets/avatarBN.imageset/avatarBN@2x.png Binary files differdeleted file mode 100644 index 6a8716577..000000000 --- a/iOSClient/Images.xcassets/avatarBN.imageset/avatarBN@2x.png +++ /dev/null diff --git a/iOSClient/Images.xcassets/avatarBN.imageset/avatarBN@3x.png b/iOSClient/Images.xcassets/avatarBN.imageset/avatarBN@3x.png Binary files differdeleted file mode 100644 index 8d56075cb..000000000 --- a/iOSClient/Images.xcassets/avatarBN.imageset/avatarBN@3x.png +++ /dev/null diff --git a/iOSClient/Images.xcassets/capabilities.imageset/Contents.json b/iOSClient/Images.xcassets/capabilities.imageset/Contents.json new file mode 100644 index 000000000..53893dc49 --- /dev/null +++ b/iOSClient/Images.xcassets/capabilities.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "capabilities.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/iOSClient/Images.xcassets/capabilities.imageset/capabilities.pdf b/iOSClient/Images.xcassets/capabilities.imageset/capabilities.pdf Binary files differnew file mode 100644 index 000000000..d0ae19117 --- /dev/null +++ b/iOSClient/Images.xcassets/capabilities.imageset/capabilities.pdf diff --git a/iOSClient/Images.xcassets/cloudDownload.imageset/Contents.json b/iOSClient/Images.xcassets/cloudDownload.imageset/Contents.json new file mode 100644 index 000000000..63c160122 --- /dev/null +++ b/iOSClient/Images.xcassets/cloudDownload.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "cloudDownload.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/iOSClient/Images.xcassets/cloudDownload.imageset/cloudDownload.pdf b/iOSClient/Images.xcassets/cloudDownload.imageset/cloudDownload.pdf Binary files differnew file mode 100644 index 000000000..600f62fed --- /dev/null +++ b/iOSClient/Images.xcassets/cloudDownload.imageset/cloudDownload.pdf diff --git a/iOSClient/Images.xcassets/cloudUpload.imageset/Contents.json b/iOSClient/Images.xcassets/cloudUpload.imageset/Contents.json new file mode 100644 index 000000000..8d7e531cd --- /dev/null +++ b/iOSClient/Images.xcassets/cloudUpload.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "cloudUpload.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/iOSClient/Images.xcassets/cloudUpload.imageset/cloudUpload.pdf b/iOSClient/Images.xcassets/cloudUpload.imageset/cloudUpload.pdf Binary files differnew file mode 100644 index 000000000..a2db324c0 --- /dev/null +++ b/iOSClient/Images.xcassets/cloudUpload.imageset/cloudUpload.pdf diff --git a/iOSClient/Images.xcassets/uploadCloud.imageset/Contents.json b/iOSClient/Images.xcassets/uploadCloud.imageset/Contents.json deleted file mode 100644 index 206c04fe8..000000000 --- a/iOSClient/Images.xcassets/uploadCloud.imageset/Contents.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "uploadCloud.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "uploadCloud@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "uploadCloud@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - }, - "properties" : { - "template-rendering-intent" : "template" - } -}
\ No newline at end of file diff --git a/iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud.png b/iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud.png Binary files differdeleted file mode 100644 index 102f8d472..000000000 --- a/iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud.png +++ /dev/null diff --git a/iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud@2x.png b/iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud@2x.png Binary files differdeleted file mode 100644 index 07d44e7f3..000000000 --- a/iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud@2x.png +++ /dev/null diff --git a/iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud@3x.png b/iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud@3x.png Binary files differdeleted file mode 100644 index d49836001..000000000 --- a/iOSClient/Images.xcassets/uploadCloud.imageset/uploadCloud@3x.png +++ /dev/null diff --git a/iOSClient/Login/NCAppConfigView.swift b/iOSClient/Login/NCAppConfigView.swift index 4d96e86cc..8ee73496e 100644 --- a/iOSClient/Login/NCAppConfigView.swift +++ b/iOSClient/Login/NCAppConfigView.swift @@ -61,15 +61,15 @@ class NCAppConfigView: UIViewController { appDelegate.timerErrorNetworking.invalidate() guard let serverUrl = self.serverUrl else { - NCContentPresenter.shared.messageNotification("_error_", description: "User Default, serverUrl not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0) + NCContentPresenter.shared.messageNotification("_error_", description: "User Default, serverUrl not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true) return } guard let username = self.username else { - NCContentPresenter.shared.messageNotification("_error_", description: "User Default, username not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0) + NCContentPresenter.shared.messageNotification("_error_", description: "User Default, username not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true) return } guard let password = self.password else { - NCContentPresenter.shared.messageNotification("_error_", description: "User Default, password not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0) + NCContentPresenter.shared.messageNotification("_error_", description: "User Default, password not found", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true) return } @@ -86,7 +86,7 @@ class NCAppConfigView: UIViewController { NCManageDatabase.sharedInstance.addAccount(account, url: serverUrl, user: username, password: token!) guard let tableAccount = NCManageDatabase.sharedInstance.setAccountActive(account) else { - NCContentPresenter.shared.messageNotification("_error_", description: "setAccountActive error", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0) + NCContentPresenter.shared.messageNotification("_error_", description: "setAccountActive error", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true) self.dismiss(animated: true, completion: nil) return } diff --git a/iOSClient/Login/NCLoginWeb.swift b/iOSClient/Login/NCLoginWeb.swift index b2a5a1f10..db0651610 100644 --- a/iOSClient/Login/NCLoginWeb.swift +++ b/iOSClient/Login/NCLoginWeb.swift @@ -78,7 +78,7 @@ class NCLoginWeb: UIViewController { if let url = URL(string: urlBase) { loadWebPage(webView: webView!, url: url) } else { - NCContentPresenter.shared.messageNotification("_error_", description: "_login_url_error_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0) + NCContentPresenter.shared.messageNotification("_error_", description: "_login_url_error_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true) } } @@ -138,7 +138,7 @@ extension NCLoginWeb: WKNavigationDelegate { if server != "" && user != "" && password != "" { let server: String = server.replacingOccurrences(of: "/server:", with: "") - let username: String = user.replacingOccurrences(of: "user:", with: "") + let username: String = user.replacingOccurrences(of: "user:", with: "").replacingOccurrences(of: "+", with: " ") let password: String = password.replacingOccurrences(of: "password:", with: "") createAccount(server: server, username: username, password: password) diff --git a/iOSClient/Main/CCMain.m b/iOSClient/Main/CCMain.m index 50d75f7d6..26f174d46 100644 --- a/iOSClient/Main/CCMain.m +++ b/iOSClient/Main/CCMain.m @@ -23,7 +23,6 @@ #import "CCMain.h" #import "AppDelegate.h" -#import "CCSynchronize.h" #import "NCAutoUpload.h" #import "NCBridgeSwift.h" #import "PKDownloadButton.h" @@ -138,6 +137,7 @@ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moveFile:) name:k_notificationCenter_moveFile object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(copyFile:) name:k_notificationCenter_copyFile object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeTheming) name:k_notificationCenter_changeTheming object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(createFolder:) name:k_notificationCenter_createFolder object:nil]; // Search self.definesPresentationContext = YES; @@ -432,6 +432,21 @@ #pragma mark ==== NotificationCenter ==== #pragma -------------------------------------------------------------------------------------------- +- (void)createFolder:(NSNotification *)notification +{ + NSDictionary *userInfo = notification.userInfo; + NSString *serverUrl = userInfo[@"serverUrl"]; + NSInteger errorCode = [userInfo[@"errorCode"] integerValue]; + + if (![serverUrl isEqualToString:self.serverUrl]) { return; } + if (errorCode == 0) { + BOOL isFolderEncrypted = [CCUtility isFolderEncrypted:serverUrl e2eEncrypted:nil account:appDelegate.activeAccount]; + if (isFolderEncrypted) { + [self readFolder:serverUrl]; + } + } +} + - (void)deleteFile:(NSNotification *)notification { NSDictionary *userInfo = notification.userInfo; @@ -458,7 +473,7 @@ } if (errorCode != 0 && self.view.window != nil) { - [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode]; + [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:false]; } } @@ -481,7 +496,7 @@ } if (errorCode != 0 && self.view.window != nil) { - [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode]; + [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:false]; } } @@ -504,7 +519,7 @@ } if (errorCode != 0 && self.view.window != nil) { - [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode]; + [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:false]; } } @@ -524,23 +539,17 @@ } if (metadata.directory && favorite) { - - NSString *selector; - - if ([CCUtility getFavoriteOffline]) - selector = selectorReadFolderWithDownload; - else - selector = selectorReadFolder; - - [[CCSynchronize sharedSynchronize] readFolder:[CCUtility stringAppendServerUrl:self.serverUrl addFileName:metadata.fileName] selector:selector account:appDelegate.activeAccount]; - } - - if (!metadata.directory && favorite && [CCUtility getFavoriteOffline]) { - + if ([CCUtility getFavoriteOffline]) { + [[NCOperationQueue shared] synchronizationMetadata:metadata selector:selectorDownloadSynchronize]; + } else { + [[NCOperationQueue shared] synchronizationMetadata:metadata selector:selectorSynchronize]; + } + } else if (!metadata.directory && favorite && [CCUtility getFavoriteOffline]) { [[NCNetworking shared] downloadWithMetadata:metadata selector:selectorDownloadSynchronize setFavorite:true completion:^(NSInteger errorCode) { }]; } + } else { - [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode]; + [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:false]; } } @@ -764,7 +773,7 @@ if ([data writeToFile:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileName] options:NSDataWritingAtomic error:&error]) { - tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:ocId serverUrl:serverUrl url:@"" contentType:@""]; + tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:ocId serverUrl:serverUrl urlBase:appDelegate.activeUrl url:@"" contentType:@""]; metadataForUpload.session = NCCommunicationCommon.shared.sessionIdentifierBackground; metadataForUpload.sessionSelector = selectorUploadFile; @@ -787,12 +796,12 @@ } else { - [[NCContentPresenter shared] messageNotification:@"_error_" description:error.description delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code]; + [[NCContentPresenter shared] messageNotification:@"_error_" description:error.description delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code forced:false]; } } else { - [[NCContentPresenter shared] messageNotification:@"_error_" description:@"_read_file_error_" delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code]; + [[NCContentPresenter shared] messageNotification:@"_error_" description:@"_read_file_error_" delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code forced:false]; } }]; } @@ -854,7 +863,7 @@ if (image) UIImageWriteToSavedPhotosAlbum(image, self, @selector(saveSelectedFilesSelector: didFinishSavingWithError: contextInfo:), nil); else - [[NCContentPresenter shared] messageNotification:@"_save_selected_files_" description:@"_file_not_saved_cameraroll_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError]; + [[NCContentPresenter shared] messageNotification:@"_save_selected_files_" description:@"_file_not_saved_cameraroll_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorFileNotSaved forced:false]; } if ([metadata.typeFile isEqualToString: k_metadataTypeFile_video] && status == PHAuthorizationStatusAuthorized) { @@ -863,7 +872,7 @@ UISaveVideoAtPathToSavedPhotosAlbum(fileNamePath, self, @selector(saveSelectedFilesSelector: didFinishSavingWithError: contextInfo:), nil); } else { - [[NCContentPresenter shared] messageNotification:@"_save_selected_files_" description:@"_file_not_saved_cameraroll_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError]; + [[NCContentPresenter shared] messageNotification:@"_save_selected_files_" description:@"_file_not_saved_cameraroll_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorFileNotSaved forced:false]; } } @@ -880,7 +889,7 @@ - (void)saveSelectedFilesSelector:(NSString *)path didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo { if (error) { - [[NCContentPresenter shared] messageNotification:@"_save_selected_files_" description:@"_file_not_saved_cameraroll_" delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code]; + [[NCContentPresenter shared] messageNotification:@"_save_selected_files_" description:@"_file_not_saved_cameraroll_" delay:k_dismissAfterSecond type:messageTypeError errorCode:error.code forced:false]; } } @@ -955,29 +964,12 @@ { if (_isSelectedMode && [_selectedocIdsMetadatas count] == 0) return; - - NSLog(@"[LOG] Start download selected ..."); - - [_hud visibleHudTitle:NSLocalizedString(@"_downloading_progress_", nil) mode:MBProgressHUDModeIndeterminate color:nil]; NSArray *selectedMetadatas = [self getMetadatasFromSelectedRows:[self.tableView indexPathsForSelectedRows]]; - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) { - for (tableMetadata *metadata in selectedMetadatas) { - - if (metadata.directory) { - - [[CCSynchronize sharedSynchronize] readFolder:[CCUtility stringAppendServerUrl:metadata.serverUrl addFileName:metadata.fileName] selector:selectorReadFolderWithDownload account:appDelegate.activeAccount]; - - } else { - - [[CCSynchronize sharedSynchronize] readFile:metadata.ocId fileName:metadata.fileName serverUrl:metadata.serverUrl selector:selectorReadFileWithDownload account:appDelegate.activeAccount]; - } - } - - [_hud hideHud]; - }); + for (tableMetadata *metadata in selectedMetadatas) { + [[NCOperationQueue shared] synchronizationMetadata:metadata selector:selectorDownloadSynchronize]; + } [self tableViewSelect:false]; } @@ -1029,12 +1021,12 @@ } // Check if is in upload - NSArray *isRecordInSessions = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND fileName == %@ AND session != ''", appDelegate.activeAccount, serverUrl, fileName] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:YES]; + NSArray *isRecordInSessions = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND fileName == %@ AND session != ''", appDelegate.activeAccount, serverUrl, fileName] page:0 limit:0 sorted:@"fileName" ascending:NO]; if ([isRecordInSessions count] > 0) continue; // Prepare record metadata - tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl url:@"" contentType:@""]; + tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl urlBase:appDelegate.activeUrl url:@"" contentType:@""]; metadataForUpload.assetLocalIdentifier = asset.localIdentifier; metadataForUpload.session = session; @@ -1057,7 +1049,7 @@ NSString *fileName = [NSString stringWithFormat:@"%@.mov", fileNameNoExt]; unsigned long long fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:url.path error:nil] fileSize]; - tableMetadata *metadataMOVForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl url:@"" contentType:@""]; + tableMetadata *metadataMOVForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrl urlBase:appDelegate.activeUrl url:@"" contentType:@""]; metadataMOVForUpload.session = session; metadataMOVForUpload.sessionSelector = selectorUploadFile; @@ -1117,7 +1109,7 @@ [refreshControl endRefreshing]; [self tableViewReloadData]; - [[NCNetworking shared] readFolderWithServerUrl:serverUrl account:appDelegate.activeAccount completion:^(NSString *account, tableMetadata *metadataFolder, NSArray *metadatas, NSInteger errorCode, NSString *errorDescription) { + [[NCNetworking shared] readFolderWithServerUrl:serverUrl account:appDelegate.activeAccount completion:^(NSString *account, tableMetadata *metadataFolder, NSArray *metadatas, NSArray *metadatasChanged, NSInteger errorCode, NSString *errorDescription) { if (errorCode == 0 ) { @@ -1125,9 +1117,13 @@ BOOL isFolderEncrypted = [CCUtility isFolderEncrypted:serverUrl e2eEncrypted:_metadataFolder.e2eEncrypted account:appDelegate.activeAccount]; [self setTitle]; - // File is changed ?? dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ - [[CCSynchronize sharedSynchronize] verifyChangeMedatas:metadatas serverUrl:serverUrl account:account withDownload:NO]; + for (tableMetadata *metadata in metadatasChanged) { + tableLocalFile *localFile = [[NCManageDatabase sharedInstance] getTableLocalFileWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", metadata.ocId]]; + if (localFile != nil) { + [[NCNetworking shared] downloadWithMetadata:metadata selector:selectorDownloadSynchronize setFavorite:false completion:^(NSInteger errorCode) { }]; + } + } }); // E2EE Is encrypted folder get metadata @@ -1141,26 +1137,29 @@ BOOL result = [[NCEndToEndMetadata sharedInstance] decoderMetadata:e2eMetadata privateKey:[CCUtility getEndToEndPrivateKey:account] serverUrl:self.serverUrl account:account url:appDelegate.activeUrl]; if (result == false) { - [[NCContentPresenter shared] messageNotification:@"_error_e2ee_" description:@"_e2e_error_decode_metadata_" delay:k_dismissAfterSecond type:messageTypeError errorCode:-999]; + [[NCContentPresenter shared] messageNotification:@"_error_e2ee_" description:@"_e2e_error_decode_metadata_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorDecodeMetadata forced:true]; } } else if (errorCode != 404) { - [[NCContentPresenter shared] messageNotification:@"_e2e_error_get_metadata_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode]; + [[NCContentPresenter shared] messageNotification:@"_e2e_error_get_metadata_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:true]; } + + [self reloadDatasource:_serverUrl ocId:nil]; }]; } else { - [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0]; + [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorE2EENotEnabled forced:true]; } } } else { - [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode]; + [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:true]; } _loadingFolder = NO; + [self reloadDatasource:serverUrl ocId:nil]; }]; } @@ -1186,7 +1185,7 @@ } } else if (errorCode != 0) { - [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode]; + [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:false]; } }]; } @@ -1208,8 +1207,8 @@ [[NCManageDatabase sharedInstance] convertNCCommunicationFilesToMetadatas:files useMetadataFolder:false account:account completion:^(tableMetadata *metadataFolder, NSArray<tableMetadata *> *metadatasFolder, NSArray<tableMetadata *> *metadatas) { - NSMutableArray *metadatasDB = (NSMutableArray *)[[NCManageDatabase sharedInstance] addMetadatas:metadatas]; - _searchResultMetadatas = [[NSMutableArray alloc] initWithArray:metadatasDB]; + [[NCManageDatabase sharedInstance] addMetadatas:metadatas]; + _searchResultMetadatas = [[NSMutableArray alloc] initWithArray:metadatas]; _metadataFolder = nil; [self reloadDatasource:_serverUrl ocId:nil]; @@ -1220,10 +1219,11 @@ } else { if (errorCode != 0) { - [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode]; + [[NCContentPresenter shared] messageNotification:@"_error_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:true]; } _searchFileName = @""; + [self cancelSearchBar]; } }]; @@ -1251,7 +1251,7 @@ // First : filter - NSArray *records = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND fileNameView CONTAINS[cd] %@", appDelegate.activeAccount, _serverUrl, fileName] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO]; + NSArray *records = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND fileNameView CONTAINS[cd] %@", appDelegate.activeAccount, _serverUrl, fileName] page:0 limit:0 sorted:@"fileName" ascending:NO]; [_searchResultMetadatas removeAllObjects]; for (tableMetadata *record in records) { @@ -1374,7 +1374,7 @@ // E2EE DENIED if ([CCUtility isFolderEncrypted:serverUrl e2eEncrypted:metadata.e2eEncrypted account:appDelegate.activeAccount]) { - [[NCContentPresenter shared] messageNotification:@"_move_" description:@"Not possible move files to encrypted directory" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0]; + [[NCContentPresenter shared] messageNotification:@"_move_" description:@"_e2e_error_not_move_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorE2EENotMove forced:true]; return; } @@ -1479,10 +1479,7 @@ tableMetadata *metadataSection = [[NCMainCommon sharedInstance] getMetadataFromSectionDataSourceIndexPath:indexPath sectionDataSource:sectionDataSource]; if (metadataSection) { - - tableMetadata *metadata = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", metadataSection.ocId]]; - if (metadata) - [[NCMainCommon sharedInstance] cancelTransferMetadata:metadata reloadDatasource:true uploadStatusForcedStart:false]; + [[NCMainCommon sharedInstance] cancelTransferMetadata:metadataSection reloadDatasource:true uploadStatusForcedStart:false]; } } } @@ -1830,7 +1827,7 @@ [CCUtility copyFileAtPath:[CCUtility getDirectoryProviderStorageOcId:metadata.ocId fileNameView:metadata.fileNameView] toPath:[CCUtility getDirectoryProviderStorageOcId:ocId fileNameView:fileName]]; // Prepare record metadata - tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:ocId serverUrl:self.serverUrl url:@"" contentType:@""]; + tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:ocId serverUrl:self.serverUrl urlBase:appDelegate.activeUrl url:@"" contentType:@""]; metadataForUpload.session = NCCommunicationCommon.shared.sessionIdentifierBackground; metadataForUpload.sessionSelector = selectorUploadFile; @@ -1853,7 +1850,7 @@ - (BOOL)canOpenMenuAction:(tableMetadata *)metadata { - if (metadata == nil || _metadataFolder == nil || [[NCManageDatabase sharedInstance] isTableInvalidated:metadata] || metadata.status != k_metadataStatusNormal || [[NCManageDatabase sharedInstance] isTableInvalidated:_metadataFolder]) + if (metadata == nil) return NO; // E2EE @@ -2011,7 +2008,7 @@ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSArray *recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.activeAccount, serverUrl] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO]; + NSArray *recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@", appDelegate.activeAccount, serverUrl] page:0 limit:0 sorted:@"fileName" ascending:NO]; // [CCUtility getGroupBySettings] CCSectionDataSourceMetadata *sectionDataSourceTemp = [CCSectionMetadata creataDataSourseSectionMetadata:recordsTableMetadata listProgressMetadata:nil groupByField:nil filterTypeFileImage:NO filterTypeFileVideo:NO filterLivePhoto:YES sorted:[CCUtility getOrderSettings] ascending:[CCUtility getAscendingSettings] activeAccount:appDelegate.activeAccount]; @@ -2461,7 +2458,7 @@ if (_metadataFolder.e2eEncrypted && ![CCUtility isEndToEndEnabled:appDelegate.activeAccount]) { - [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0]; + [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorE2EENotEnabled forced:true]; } else { @@ -2474,7 +2471,7 @@ if (NCCommunication.shared.isNetworkReachable) { [self shouldPerformSegue:self.metadata selector:@""]; } else { - [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0]; + [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorOffline forced:true]; } } else if ([self.metadata.typeFile isEqualToString: k_metadataTypeFile_document] && [[NCUtility sharedInstance] isRichDocument:self.metadata]) { @@ -2482,7 +2479,7 @@ if (NCCommunication.shared.isNetworkReachable) { [self shouldPerformSegue:self.metadata selector:@""]; } else { - [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0]; + [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_go_online_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorOffline forced:true]; } } else { @@ -2610,7 +2607,7 @@ // E2EE Check enable if (metadata.e2eEncrypted && [CCUtility isEndToEndEnabled:appDelegate.activeAccount] == NO) { - [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:0]; + [[NCContentPresenter shared] messageNotification:@"_info_" description:@"_e2e_goto_settings_for_enable_" delay:k_dismissAfterSecond type:messageTypeInfo errorCode:k_CCErrorE2EENotEnabled forced:true]; return; } diff --git a/iOSClient/Main/Create cloud/NCCreateFormUploadAssets.swift b/iOSClient/Main/Create cloud/NCCreateFormUploadAssets.swift index f30e4e0b2..6ea38e39d 100644 --- a/iOSClient/Main/Create cloud/NCCreateFormUploadAssets.swift +++ b/iOSClient/Main/Create cloud/NCCreateFormUploadAssets.swift @@ -277,7 +277,7 @@ class NCCreateFormUploadAssets: XLFormViewController, NCSelectDelegate { self.reloadFormRow(formRow) - NCContentPresenter.shared.messageNotification("_info_", description: "_forbidden_characters_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0) + NCContentPresenter.shared.messageNotification("_info_", description: "_forbidden_characters_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorCharactersForbidden), forced: true) } } diff --git a/iOSClient/Main/Create cloud/NCCreateFormUploadConflict.swift b/iOSClient/Main/Create cloud/NCCreateFormUploadConflict.swift index c866b2b29..773c8ef95 100644 --- a/iOSClient/Main/Create cloud/NCCreateFormUploadConflict.swift +++ b/iOSClient/Main/Create cloud/NCCreateFormUploadConflict.swift @@ -148,7 +148,7 @@ extension NCCreateFormUploadConflictDelegate { } switchAlreadyExistingFiles.isOn = true - NCContentPresenter.shared.messageNotification("_info_", description: "_file_not_rewite_doc_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0) + NCContentPresenter.shared.messageNotification("_info_", description: "_file_not_rewite_doc_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true) } tableView.reloadData() diff --git a/iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift b/iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift index c1a45c363..29c7d5a93 100644 --- a/iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift +++ b/iOSClient/Main/Create cloud/NCCreateFormUploadDocuments.swift @@ -274,7 +274,7 @@ import NCCommunication if NCUtility.sharedInstance.getMetadataConflict(account: appDelegate.activeAccount, serverUrl: serverUrl, fileName: String(describing: fileNameForm)) != nil { - let metadataForUpload = NCManageDatabase.sharedInstance.createMetadata(account: appDelegate.activeAccount, fileName: String(describing: fileNameForm), ocId: "", serverUrl: serverUrl, url: "", contentType: "") + let metadataForUpload = NCManageDatabase.sharedInstance.createMetadata(account: appDelegate.activeAccount, fileName: String(describing: fileNameForm), ocId: "", serverUrl: serverUrl, urlBase: appDelegate.activeUrl, url: "", contentType: "") guard let conflictViewController = UIStoryboard(name: "NCCreateFormUploadConflict", bundle: nil).instantiateInitialViewController() as? NCCreateFormUploadConflict else { return } conflictViewController.textLabelDetailNewFile = NSLocalizedString("_now_", comment: "") @@ -328,7 +328,7 @@ import NCCommunication let result = NCCommunicationCommon.shared.getInternalContenType(fileName: fileName, contentType: "", directory: false) self.dismiss(animated: true, completion: { - let metadata = NCManageDatabase.sharedInstance.createMetadata(account: self.appDelegate.activeAccount, fileName: fileName, ocId: CCUtility.createRandomString(12), serverUrl: self.serverUrl, url: url ?? "", contentType: result.contentType) + let metadata = NCManageDatabase.sharedInstance.createMetadata(account: self.appDelegate.activeAccount, fileName: fileName, ocId: CCUtility.createRandomString(12), serverUrl: self.serverUrl, urlBase: self.appDelegate.activeUrl, url: url ?? "", contentType: result.contentType) self.appDelegate.activeMain.readFileReloadFolder() self.appDelegate.activeMain.shouldPerformSegue(metadata, selector: "") }) @@ -351,7 +351,7 @@ import NCCommunication self.dismiss(animated: true, completion: { - let metadata = NCManageDatabase.sharedInstance.createMetadata(account: self.appDelegate.activeAccount, fileName: (fileName as NSString).deletingPathExtension + "." + self.fileNameExtension, ocId: CCUtility.createRandomString(12), serverUrl: self.serverUrl, url: url!, contentType: "") + let metadata = NCManageDatabase.sharedInstance.createMetadata(account: self.appDelegate.activeAccount, fileName: (fileName as NSString).deletingPathExtension + "." + self.fileNameExtension, ocId: CCUtility.createRandomString(12), serverUrl: self.serverUrl, urlBase: self.appDelegate.activeUrl, url: url!, contentType: "") self.appDelegate.activeMain.shouldPerformSegue(metadata, selector: "") }) diff --git a/iOSClient/Main/Create cloud/NCCreateFormUploadScanDocument.swift b/iOSClient/Main/Create cloud/NCCreateFormUploadScanDocument.swift index 6773b8cb4..4c3f7fdff 100644 --- a/iOSClient/Main/Create cloud/NCCreateFormUploadScanDocument.swift +++ b/iOSClient/Main/Create cloud/NCCreateFormUploadScanDocument.swift @@ -25,10 +25,7 @@ import Foundation import WeScan import NCCommunication - -#if GOOGLEMOBILEVISION -import GoogleMobileVision -#endif +import Vision class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NCCreateFormUploadConflictDelegate { @@ -46,10 +43,6 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC var password: String = "" var fileType = "PDF" - #if GOOGLEMOBILEVISION - var textDetector: GMVDetector? - #endif - let appDelegate = UIApplication.shared.delegate as! AppDelegate convenience init(serverUrl: String, arrayImages: [UIImage]) { @@ -88,10 +81,6 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC // let rowCell = row.cell(forForm: self) // rowCell.becomeFirstResponder() - #if GOOGLEMOBILEVISION - textDetector = GMVDetector(ofType: GMVDetectorTypeText, options: nil) - #endif - // Theming view NotificationCenter.default.addObserver(self, selector: #selector(changeTheming), name: NSNotification.Name(rawValue: k_notificationCenter_changeTheming), object: nil) changeTheming() @@ -170,22 +159,21 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC // Section: Text recognition - - #if GOOGLEMOBILEVISION - section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_text_recognition_", comment: "")) - form.addFormSection(section) - - row = XLFormRowDescriptor(tag: "textRecognition", rowType: XLFormRowDescriptorTypeBooleanSwitch, title: NSLocalizedString("_text_recognition_", comment: "")) - row.value = 0 - row.cellConfig["backgroundColor"] = NCBrandColor.sharedInstance.backgroundForm + if #available(iOS 13.0, *) { + section = XLFormSectionDescriptor.formSection(withTitle: NSLocalizedString("_text_recognition_", comment: "")) + form.addFormSection(section) + + row = XLFormRowDescriptor(tag: "textRecognition", rowType: XLFormRowDescriptorTypeBooleanSwitch, title: NSLocalizedString("_text_recognition_", comment: "")) + row.value = 0 + row.cellConfig["backgroundColor"] = NCBrandColor.sharedInstance.backgroundForm - row.cellConfig["imageView.image"] = CCGraphics.changeThemingColorImage(UIImage(named: "textRecognition")!, width: 50, height: 50, color: NCBrandColor.sharedInstance.brandElement) as UIImage - - row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0) - row.cellConfig["textLabel.textColor"] = NCBrandColor.sharedInstance.textView + row.cellConfig["imageView.image"] = CCGraphics.changeThemingColorImage(UIImage(named: "textRecognition")!, width: 50, height: 50, color: NCBrandColor.sharedInstance.brandElement) as UIImage + + row.cellConfig["textLabel.font"] = UIFont.systemFont(ofSize: 15.0) + row.cellConfig["textLabel.textColor"] = NCBrandColor.sharedInstance.textView - section.addFormRow(row) - #endif + section.addFormRow(row) + } // Section: File @@ -242,7 +230,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC rowFileTape.value = "PDF" fileType = "PDF" rowPassword.disabled = true - rowCompressionQuality.disabled = true + rowCompressionQuality.disabled = false } else { if arrayImages.count == 1 { rowFileTape.selectorOptions = ["PDF","JPG"] @@ -410,7 +398,7 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC } //Create metadata for upload - let metadataForUpload = NCManageDatabase.sharedInstance.createMetadata(account: appDelegate.activeAccount, fileName: fileNameSave, ocId: UUID().uuidString, serverUrl: serverUrl, url: appDelegate.activeUrl, contentType: "") + let metadataForUpload = NCManageDatabase.sharedInstance.createMetadata(account: appDelegate.activeAccount, fileName: fileNameSave, ocId: UUID().uuidString, serverUrl: serverUrl, urlBase: appDelegate.activeUrl, url: "", contentType: "") metadataForUpload.session = NCCommunicationCommon.shared.sessionIdentifierBackground metadataForUpload.sessionSelector = selectorUploadFile @@ -427,15 +415,21 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC self.present(conflictViewController, animated: true, completion: nil) } else { - - dismissAndUpload(metadataForUpload) + + NCUtility.sharedInstance.startActivityIndicator(view: self.view) + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + self.dismissAndUpload(metadataForUpload) + } } } func dismissCreateFormUploadConflict(metadatas: [tableMetadata]?) { if metadatas != nil && metadatas!.count > 0 { - + + NCUtility.sharedInstance.startActivityIndicator(view: self.view) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self.dismissAndUpload(metadatas![0]) } @@ -445,42 +439,50 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC func dismissAndUpload(_ metadata: tableMetadata) { guard let fileNameGenerateExport = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView) else { - NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0) + NCUtility.sharedInstance.stopActivityIndicator() + NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorCreationFile), forced: true) return } - // - - #if GOOGLEMOBILEVISION // Text Recognition TXT if fileType == "TXT" && self.form.formRow(withTag: "textRecognition")!.value as! Int == 1 { var textFile = "" - for image in self.arrayImages { - guard let features = self.textDetector?.features(in: image, options: nil) as? [GMVTextBlockFeature] else { - continue - } - - for textBlock in features { + if #available(iOS 13.0, *) { - guard let text = textBlock.value else { - continue + let requestHandler = VNImageRequestHandler(cgImage: image.cgImage!, options: [:]) + + let request = VNRecognizeTextRequest { (request, error) in + guard let observations = request.results as? [VNRecognizedTextObservation] else { + NCUtility.sharedInstance.stopActivityIndicator() + return + } + for observation in observations { + guard let textLine = observation.topCandidates(1).first else { + continue + } + + textFile += textLine.string + textFile += "\n" + } } - textFile = textFile + text + "\n\n" - } - - do { - try textFile.write(to: NSURL(fileURLWithPath: fileNameGenerateExport) as URL , atomically: true, encoding: .utf8) - } catch { - NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0) - return + request.recognitionLevel = .accurate + request.usesLanguageCorrection = true + try? requestHandler.perform([request]) } } + + do { + try textFile.write(to: NSURL(fileURLWithPath: fileNameGenerateExport) as URL , atomically: true, encoding: .utf8) + } catch { + NCUtility.sharedInstance.stopActivityIndicator() + NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorCreationFile), forced: true) + return + } } - #endif if fileType == "PDF" { @@ -492,51 +494,62 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC UIGraphicsBeginPDFContextToData(pdfData, CGRect.zero, nil) } let context = UIGraphicsGetCurrentContext() + var fontColor = UIColor.clear + #if targetEnvironment(simulator) + fontColor = UIColor.red + #endif for var image in self.arrayImages { - #if GOOGLEMOBILEVISION - if self.form.formRow(withTag: "textRecognition")!.value as! Int == 1 { - - UIGraphicsBeginPDFPageWithInfo(CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height), nil) - UIImageView.init(image:image).layer.render(in: context!) + image = changeImageFromQuality(image, dpiQuality: dpiQuality) + image = changeCompressionImage(image, dpiQuality: dpiQuality) + + if #available(iOS 13.0, *) { - if let features = self.textDetector?.features(in: image, options: nil) as? [GMVTextBlockFeature] { - for textBlock in features { - for textLine in textBlock.lines { - - let bounds = textLine.bounds - let text = textLine.value! - var fontColor = UIColor.clear - - #if targetEnvironment(simulator) - fontColor = UIColor.red - #endif - - //print(text) + if self.form.formRow(withTag: "textRecognition")!.value as! Int == 1 { + + UIGraphicsBeginPDFPageWithInfo(CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height), nil) + UIImageView.init(image:image).layer.render(in: context!) + + let requestHandler = VNImageRequestHandler(cgImage: image.cgImage!, options: [:]) + + let request = VNRecognizeTextRequest { (request, error) in + guard let observations = request.results as? [VNRecognizedTextObservation] else { + NCUtility.sharedInstance.stopActivityIndicator() + return + } + for observation in observations { + guard let textLine = observation.topCandidates(1).first else { + continue + } - let font = UIFont.systemFont(ofSize: bounds.size.height, weight: .regular) - let bestFittingFont = NCUtility.sharedInstance.bestFittingFont(for: text, in: bounds, fontDescriptor: font.fontDescriptor) + var t: CGAffineTransform = CGAffineTransform.identity + t = t.scaledBy(x: image.size.width, y: -image.size.height) + t = t.translatedBy(x: 0, y: -1) + let rect = observation.boundingBox.applying(t) + + let font = UIFont.systemFont(ofSize: rect.size.height, weight: .regular) + let bestFont = self.bestFittingFont(for: textLine.string, in: rect, fontDescriptor: font.fontDescriptor) - text.draw(in: bounds, withAttributes: [NSAttributedString.Key.font: bestFittingFont, NSAttributedString.Key.foregroundColor: fontColor]) + textLine.string.draw(in: rect, withAttributes: [NSAttributedString.Key.font: bestFont, NSAttributedString.Key.foregroundColor: fontColor]) } } + + request.recognitionLevel = .accurate + request.usesLanguageCorrection = true + try? requestHandler.perform([request]) + + } else { + + UIGraphicsBeginPDFPageWithInfo(CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height), nil) + UIImageView.init(image:image).layer.render(in: context!) } } else { - image = changeImageFromQuality(image, dpiQuality: dpiQuality) - UIGraphicsBeginPDFPageWithInfo(CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height), nil) UIImageView.init(image:image).layer.render(in: context!) } - #else - image = changeImageFromQuality(image, dpiQuality: dpiQuality) - image = changeCompressionImage(image, dpiQuality: dpiQuality) - - UIGraphicsBeginPDFPageWithInfo(CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height), nil) - UIImageView.init(image:image).layer.render(in: context!) - #endif } UIGraphicsEndPDFContext(); @@ -553,18 +566,22 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC let image = changeImageFromQuality(self.arrayImages[0], dpiQuality: dpiQuality) guard let data = image.jpegData(compressionQuality: CGFloat(0.5)) else { - NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0) + NCUtility.sharedInstance.stopActivityIndicator() + NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorCreationFile), forced: true) return } do { try data.write(to: NSURL.fileURL(withPath: fileNameGenerateExport), options: .atomic) } catch { - NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0) + NCUtility.sharedInstance.stopActivityIndicator() + NCContentPresenter.shared.messageNotification("_error_", description: "_error_creation_file_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorCreationFile), forced: true) return } } + NCUtility.sharedInstance.stopActivityIndicator() + NCManageDatabase.sharedInstance.addMetadata(metadata) appDelegate.networkingAutoUpload.startProcess() @@ -664,6 +681,31 @@ class NCCreateFormUploadScanDocument: XLFormViewController, NCSelectDelegate, NC return imageCompressed } + + func bestFittingFont(for text: String, in bounds: CGRect, fontDescriptor: UIFontDescriptor) -> UIFont { + + let constrainingDimension = min(bounds.width, bounds.height) + let properBounds = CGRect(origin: .zero, size: bounds.size) + var attributes: [NSAttributedString.Key: Any] = [:] + + let infiniteBounds = CGSize(width: CGFloat.infinity, height: CGFloat.infinity) + var bestFontSize: CGFloat = constrainingDimension + + for fontSize in stride(from: bestFontSize, through: 0, by: -1) { + let newFont = UIFont(descriptor: fontDescriptor, size: fontSize) + attributes[.font] = newFont + + let currentFrame = text.boundingRect(with: infiniteBounds, options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: attributes, context: nil) + + if properBounds.contains(currentFrame) { + bestFontSize = fontSize + break + } + } + + return UIFont(descriptor: fontDescriptor, size: bestFontSize) + } + } class NCCreateScanDocument : NSObject, ImageScannerControllerDelegate { diff --git a/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift b/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift index 768132667..d99f52e12 100644 --- a/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift +++ b/iOSClient/Main/Create cloud/NCCreateFormUploadVoiceNote.swift @@ -229,7 +229,7 @@ class NCCreateFormUploadVoiceNote: XLFormViewController, NCSelectDelegate, AVAud fileNameSave = (name as! NSString).deletingPathExtension + ".m4a" } - let metadataForUpload = NCManageDatabase.sharedInstance.createMetadata(account: self.appDelegate.activeAccount, fileName: fileNameSave, ocId: UUID().uuidString, serverUrl: self.serverUrl, url: "", contentType: "") + let metadataForUpload = NCManageDatabase.sharedInstance.createMetadata(account: self.appDelegate.activeAccount, fileName: fileNameSave, ocId: UUID().uuidString, serverUrl: self.serverUrl, urlBase: self.appDelegate.activeUrl ,url: "", contentType: "") metadataForUpload.session = NCCommunicationCommon.shared.sessionIdentifierBackground metadataForUpload.sessionSelector = selectorUploadFile diff --git a/iOSClient/Main/Menu/CCMain+Menu.swift b/iOSClient/Main/Menu/CCMain+Menu.swift index b61b022ac..7bf71253f 100644 --- a/iOSClient/Main/Menu/CCMain+Menu.swift +++ b/iOSClient/Main/Menu/CCMain+Menu.swift @@ -323,7 +323,7 @@ extension CCMain { let serverUrl = CCUtility.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName)! NCManageDatabase.sharedInstance.setDirectory(serverUrl: serverUrl, offline: !isOffline, account: appDelegate.activeAccount) if (!isOffline) { - CCSynchronize.shared()?.readFolder(serverUrl, selector: selectorReadFolderWithDownload, account: appDelegate.activeAccount) + NCOperationQueue.shared.synchronizationMetadata(metadata, selector: selectorDownloadSynchronize) } NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["ocId":metadata.ocId, "serverUrl":metadata.serverUrl]) } diff --git a/iOSClient/Main/NCDetailViewController.swift b/iOSClient/Main/NCDetailViewController.swift index d57b72400..4351f3701 100644 --- a/iOSClient/Main/NCDetailViewController.swift +++ b/iOSClient/Main/NCDetailViewController.swift @@ -441,7 +441,7 @@ class NCDetailViewController: UIViewController { @objc func viewFile(metadata: tableMetadata, selector: String?) { - self.metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId), freeze: true) + self.metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) self.selector = selector self.backgroundView.image = nil diff --git a/iOSClient/Main/NCMainCommon.swift b/iOSClient/Main/NCMainCommon.swift index 00925f919..a4e05bc25 100644 --- a/iOSClient/Main/NCMainCommon.swift +++ b/iOSClient/Main/NCMainCommon.swift @@ -134,7 +134,12 @@ class NCMainCommon: NSObject, NCAudioRecorderViewControllerDelegate, UIDocumentI @objc func cancelTransferMetadata(_ metadata: tableMetadata, reloadDatasource: Bool, uploadStatusForcedStart: Bool) { - if metadata.session.count == 0 { return } + if metadata.session.count == 0 { + NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) + NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["serverUrl":metadata.serverUrl]) + return + } + let metadata = tableMetadata.init(value: metadata) if metadata.session == NCCommunicationCommon.shared.sessionIdentifierDownload { NCNetworking.shared.cancelDownload(ocId: metadata.ocId, serverUrl: metadata.serverUrl, fileNameView: metadata.fileNameView) @@ -151,8 +156,6 @@ class NCMainCommon: NSObject, NCAudioRecorderViewControllerDelegate, UIDocumentI session = NCCommunicationBackground.shared.sessionManagerTransferExtension } - var metadata = metadata - session!.getTasksWithCompletionHandler { (dataTasks, uploadTasks, downloadTasks) in var cancel = false @@ -162,7 +165,7 @@ class NCMainCommon: NSObject, NCAudioRecorderViewControllerDelegate, UIDocumentI if task.taskIdentifier == metadata.sessionTaskIdentifier { if uploadStatusForcedStart { metadata.status = Int(k_metadataStatusUploadForcedStart) - metadata = NCManageDatabase.sharedInstance.addMetadata(metadata) ?? metadata + NCManageDatabase.sharedInstance.addMetadata(metadata) } task.cancel() cancel = true @@ -190,23 +193,17 @@ class NCMainCommon: NSObject, NCAudioRecorderViewControllerDelegate, UIDocumentI NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "status == %d OR status == %d", appDelegate.activeAccount, k_metadataStatusWaitUpload, k_metadataStatusUploadError)) DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { - if let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "status != %d", k_metadataStatusNormal), sorted: "fileName", ascending: true) { - - for metadata in metadatas { - - // Modify - if (metadata.status == k_metadataStatusWaitDownload || metadata.status == k_metadataStatusDownloadError) { - metadata.session = "" - metadata.sessionSelector = "" - metadata.status = Int(k_metadataStatusNormal) - - NCManageDatabase.sharedInstance.addMetadata(metadata) - } - - // Cancel Task - if metadata.status == k_metadataStatusDownloading || metadata.status == k_metadataStatusUploading { - self.cancelTransferMetadata(metadata, reloadDatasource: false, uploadStatusForcedStart: false) - } + let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "status != %d", k_metadataStatusNormal), sorted: "fileName", ascending: true) + for metadata in metadatas { + + // Modify + if (metadata.status == k_metadataStatusWaitDownload || metadata.status == k_metadataStatusDownloadError) { + NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, session: "", sessionError: "", sessionSelector: "", sessionTaskIdentifier: 0, status: Int(k_metadataStatusNormal)) + } + + // Cancel Task + if metadata.status == k_metadataStatusDownloading || metadata.status == k_metadataStatusUploading { + self.cancelTransferMetadata(metadata, reloadDatasource: false, uploadStatusForcedStart: false) } } } @@ -306,9 +303,9 @@ class NCMainCommon: NSObject, NCAudioRecorderViewControllerDelegate, UIDocumentI // image local let size = CCUtility.fileProviderStorageSize(metadata.ocId, fileNameView: metadata.fileNameView) if size > 0 { - var tableLocalFile = NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) + let tableLocalFile = NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) if tableLocalFile == nil && size == metadata.size { - tableLocalFile = NCManageDatabase.sharedInstance.addLocalFile(metadata: metadata) + NCManageDatabase.sharedInstance.addLocalFile(metadata: metadata) } if tableLocalFile!.offline { cell.imageLocal.image = UIImage.init(named: "offlineFlag") } else { cell.imageLocal.image = UIImage.init(named: "local") } @@ -476,7 +473,9 @@ class NCMainCommon: NSObject, NCAudioRecorderViewControllerDelegate, UIDocumentI cell.filePreviewImageView.backgroundColor = UIColor.lightGray // Download preview - NCOperationQueue.shared.downloadThumbnail(metadata: metadata, activeUrl: appDelegate.activeUrl, view: tableView, indexPath: indexPath) + if !(metadataFolder?.e2eEncrypted ?? false) { + NCOperationQueue.shared.downloadThumbnail(metadata: metadata, activeUrl: appDelegate.activeUrl, view: tableView, indexPath: indexPath) + } // Share var isShare = false @@ -541,9 +540,9 @@ class NCMainCommon: NSObject, NCAudioRecorderViewControllerDelegate, UIDocumentI // Local Image - Offline let size = CCUtility.fileProviderStorageSize(metadata.ocId, fileNameView: metadata.fileNameView) if size > 0 { - var tableLocalFile = NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) + let tableLocalFile = NCManageDatabase.sharedInstance.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) if tableLocalFile == nil && size == metadata.size { - tableLocalFile = NCManageDatabase.sharedInstance.addLocalFile(metadata: metadata) + NCManageDatabase.sharedInstance.addLocalFile(metadata: metadata) } if tableLocalFile != nil && tableLocalFile!.offline { cell.local.image = UIImage.init(named: "offlineFlag") } else { cell.local.image = UIImage.init(named: "local") } @@ -672,34 +671,22 @@ class NCMainCommon: NSObject, NCAudioRecorderViewControllerDelegate, UIDocumentI if iconFileExists { cell.file.image = UIImage(contentsOfFile: CCUtility.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)) - } else if(!metadata.hasPreview){ - if metadata.iconName.count > 0 { - cell.file.image = UIImage.init(named: metadata.iconName) + } else { + if metadata.status == k_metadataStatusWaitUpload || metadata.status == k_metadataStatusInUpload || metadata.status == k_metadataStatusUploading || metadata.status == k_metadataStatusUploadError { + + cell.file.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "cloudUpload"), width: 100, height: 100, color: NCBrandColor.sharedInstance.brandElement) + } else { - cell.file.image = UIImage.init(named: "file") - } - } - - // uploadFile - if metadata.status == k_metadataStatusWaitUpload || metadata.status == k_metadataStatusInUpload || metadata.status == k_metadataStatusUploading || metadata.status == k_metadataStatusUploadError { - if (!iconFileExists) { - cell.file.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "uploadCloud"), multiplier: 2, color: NCBrandColor.sharedInstance.brandElement) + cell.file.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "cloudDownload"), width: 100, height: 100, color: NCBrandColor.sharedInstance.brandElement) } - - cell.labelTitle.isEnabled = false } // uploadFileError if metadata.status == k_metadataStatusUploadError { - cell.labelTitle.isEnabled = false cell.status.image = UIImage.init(named: "statuserror") - if !iconFileExists { - cell.file.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "uploadCloud"), multiplier: 2, color: NCBrandColor.sharedInstance.brandElement) - } - if metadata.sessionError.count == 0 { cell.labelInfoFile.text = NSLocalizedString("_error_", comment: "") + ", " + NSLocalizedString("_file_not_uploaded_", comment: "") } else { diff --git a/iOSClient/Media/NCMedia.swift b/iOSClient/Media/NCMedia.swift index a43beb2f4..00510a9d7 100644 --- a/iOSClient/Media/NCMedia.swift +++ b/iOSClient/Media/NCMedia.swift @@ -35,8 +35,9 @@ class NCMedia: UIViewController, DropdownMenuDelegate, DZNEmptyDataSetSource, DZ public var metadatas: [tableMetadata] = [] private var metadataPush: tableMetadata? + private var predicateDefault: NSPredicate? private var predicate: NSPredicate? - + private var isEditMode = false private var selectocId: [String] = [] @@ -631,12 +632,14 @@ extension NCMedia { } let startServerUrl = CCUtility.getHomeServerUrlActiveUrl(appDelegate.activeUrl) + mediaPath + predicateDefault = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND (typeFile == %@ OR typeFile == %@) AND NOT (session CONTAINS[c] 'upload')", appDelegate.activeAccount, startServerUrl, k_metadataTypeFile_image, k_metadataTypeFile_video) + if filterTypeFileImage { predicate = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND typeFile == %@ AND NOT (session CONTAINS[c] 'upload')", appDelegate.activeAccount, startServerUrl, k_metadataTypeFile_video) } else if filterTypeFileVideo { predicate = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND typeFile == %@ AND NOT (session CONTAINS[c] 'upload')", appDelegate.activeAccount, startServerUrl, k_metadataTypeFile_image) } else { - predicate = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND (typeFile == %@ OR typeFile == %@) AND NOT (session CONTAINS[c] 'upload')", appDelegate.activeAccount, startServerUrl, k_metadataTypeFile_image, k_metadataTypeFile_video) + predicate = predicateDefault } NCManageDatabase.sharedInstance.getMetadatasMedia(predicate: predicate!, sort: CCUtility.getMediaSortDate()) { (metadatas) in @@ -673,12 +676,13 @@ extension NCMedia { collectionView.reloadData() var lessDate = Date() - var greaterDate: Date - - if metadatas.count > 0 { - lessDate = metadatas.last!.date as Date + if predicateDefault != nil { + if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: predicateDefault!, sorted: "date", ascending: true) { + lessDate = metadata.date as Date + } } + var greaterDate: Date if value == -999 { greaterDate = Date.distantPast } else { @@ -695,11 +699,34 @@ extension NCMedia { self.collectionView.reloadData() if errorCode == 0 && account == self.appDelegate.activeAccount { - if files?.count ?? 0 > 0 { + if files.count > 0 { - NCManageDatabase.sharedInstance.addMetadatas(files: files, account: self.appDelegate.activeAccount) - self.reloadDataSource() + let predicateDate = NSPredicate(format: "date > %@ AND date < %@", greaterDate as NSDate, lessDate as NSDate) + let predicate = NSCompoundPredicate.init(andPredicateWithSubpredicates:[predicateDate, self.predicateDefault!]) + let metadatasResult = NCManageDatabase.sharedInstance.getMetadatas(predicate: predicate) + NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: false, account: self.appDelegate.activeAccount) { (_, _, metadatas) in + + let metadatasChanged = NCManageDatabase.sharedInstance.updateMetadatas(metadatas, metadatasResult: metadatasResult) + + if metadatasChanged.count < 100 { + + if value == -30 { + self.searchOldPhotoVideo(value: -90) + } else if value == -90 { + self.searchOldPhotoVideo(value: -180) + } else if value == -180 { + self.searchOldPhotoVideo(value: -999) + } else { + self.reloadDataSource() + } + + } else { + + self.reloadDataSource() + } + } + } else { if value == -30 { @@ -735,21 +762,20 @@ extension NCMedia { } } } - NCCommunication.shared.searchMedia(path: self.mediaPath, lessDate: lessDate, greaterDate: greaterDate, elementDate: "d:getlastmodified/" ,showHiddenFiles: CCUtility.getShowHiddenFiles(), user: self.appDelegate.activeUser) { (account, files, errorCode, errorDescription) in self.newInProgress = false - if errorCode == 0 && account == self.appDelegate.activeAccount && files?.count ?? 0 > 0 { + if errorCode == 0 && account == self.appDelegate.activeAccount && files.count > 0 { DispatchQueue.global().async { let predicate = NSPredicate(format: "date > %@ AND date < %@", greaterDate as NSDate, lessDate as NSDate) let newPredicate = NSCompoundPredicate.init(andPredicateWithSubpredicates:[predicate, self.predicate!]) - - if let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: newPredicate){ + let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: newPredicate) + if metadatas.count > 0 { let etagsMetadatas = Array(metadatas.map { $0.etag }) - let etagsFiles = Array(files!.map { $0.etag }) + let etagsFiles = Array(files.map { $0.etag }) for etag in etagsFiles { if !etagsMetadatas.contains(etag) { NCManageDatabase.sharedInstance.addMetadatas(files: files, account: self.appDelegate.activeAccount) @@ -762,7 +788,7 @@ extension NCMedia { self.reloadDataSource() } } - } else if errorCode == 0 && files?.count ?? 0 == 0 && self.metadatas.count == 0 { + } else if errorCode == 0 && files.count == 0 && self.metadatas.count == 0 { self.searchOldPhotoVideo() } } diff --git a/iOSClient/Networking/NCNetworking.swift b/iOSClient/Networking/NCNetworking.swift index 107ce852b..f39f257ac 100644 --- a/iOSClient/Networking/NCNetworking.swift +++ b/iOSClient/Networking/NCNetworking.swift @@ -44,7 +44,10 @@ import Alamofire var lastReachability: Bool = true var downloadRequest: [String: DownloadRequest] = [:] var uploadRequest: [String: UploadRequest] = [:] + + var uploadMetadata: [String: tableMetadata] = [:] + //MARK: - Communication Delegate func networkReachabilityObserver(_ typeReachability: NCCommunicationCommon.typeReachability) { @@ -161,7 +164,7 @@ import Alamofire return result } - + //MARK: - Download @objc func cancelDownload(ocId: String, serverUrl:String, fileNameView: String) { @@ -181,7 +184,7 @@ import Alamofire let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileName)! - if NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId), freeze: true) == nil { + if NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) == nil { NCManageDatabase.sharedInstance.addMetadata(tableMetadata.init(value: metadata)) } @@ -248,7 +251,7 @@ import Alamofire //MARK: - Upload @objc func cancelUpload(ocId: String) { - guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId), freeze: true) else { return } + guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocId)) else { return } guard let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView) else { return } @@ -298,16 +301,16 @@ import Alamofire return } - guard let metadataForUpload = NCManageDatabase.sharedInstance.addMetadata(metadata) else { return } + NCManageDatabase.sharedInstance.addMetadata(metadata) if e2eEncrypted { #if !EXTENSION - NCNetworkingE2EE.shared.upload(metadata: metadataForUpload, account: account, completion: completion) + NCNetworkingE2EE.shared.upload(metadata: metadata, account: account, completion: completion) #endif } else if background { - uploadFileInBackground(metadata: metadataForUpload, account: account, completion: completion) + uploadFileInBackground(metadata: metadata, account: account, completion: completion) } else { - uploadFile(metadata: metadataForUpload, account: account, completion: completion) + uploadFile(metadata: metadata, account: account, completion: completion) } } else { @@ -329,16 +332,16 @@ import Alamofire return } - guard let metadataForUpload = NCManageDatabase.sharedInstance.addMetadata(extractMetadata) else {return} + NCManageDatabase.sharedInstance.addMetadata(extractMetadata) if e2eEncrypted { #if !EXTENSION - NCNetworkingE2EE.shared.upload(metadata: metadataForUpload, account: account, completion: completion) + NCNetworkingE2EE.shared.upload(metadata: extractMetadata, account: account, completion: completion) #endif } else if background { - self.uploadFileInBackground(metadata: metadataForUpload, account: account, completion: completion) + self.uploadFileInBackground(metadata: extractMetadata, account: account, completion: completion) } else { - self.uploadFile(metadata: metadataForUpload, account: account, completion: completion) + self.uploadFile(metadata: extractMetadata, account: account, completion: completion) } } } @@ -382,9 +385,17 @@ import Alamofire func uploadProgress(_ progress: Double, totalBytes: Int64, totalBytesExpected: Int64, fileName: String, serverUrl: String, session: URLSession, task: URLSessionTask) { delegate?.uploadProgress?(progress, totalBytes: totalBytes, totalBytesExpected: totalBytesExpected, fileName: fileName, serverUrl: serverUrl, session: session, task: task) - if let metadata = NCManageDatabase.sharedInstance.getMetadataInSessionFromFileName(fileName, serverUrl: serverUrl, taskIdentifier: task.taskIdentifier, freeze: true) { - - NotificationCenter.default.postOnMainThread(name: k_notificationCenter_progressTask, userInfo: ["account":metadata.account, "ocId":metadata.ocId, "serverUrl":serverUrl, "status":NSNumber(value: k_metadataStatusInUpload), "progress":NSNumber(value: progress), "totalBytes":NSNumber(value: totalBytes), "totalBytesExpected":NSNumber(value: totalBytesExpected)]) + var metadata: tableMetadata? + + if let metadataTmp = self.uploadMetadata[fileName+serverUrl] { + metadata = metadataTmp + } else if let metadataTmp = NCManageDatabase.sharedInstance.getMetadataInSessionFromFileName(fileName, serverUrl: serverUrl, taskIdentifier: task.taskIdentifier) { + self.uploadMetadata[fileName+serverUrl] = metadataTmp + metadata = metadataTmp + } + + if metadata != nil { + NotificationCenter.default.postOnMainThread(name: k_notificationCenter_progressTask, userInfo: ["account":metadata!.account, "ocId":metadata!.ocId, "serverUrl":serverUrl, "status":NSNumber(value: k_metadataStatusInUpload), "progress":NSNumber(value: progress), "totalBytes":NSNumber(value: totalBytes), "totalBytesExpected":NSNumber(value: totalBytesExpected)]) } } @@ -393,16 +404,15 @@ import Alamofire delegate?.uploadComplete?(fileName: fileName, serverUrl: serverUrl, ocId: ocId, etag: etag, date: date, size:size, description: description, task: task, errorCode: errorCode, errorDescription: errorDescription) } else { - guard var metadata = NCManageDatabase.sharedInstance.getMetadataInSessionFromFileName(fileName, serverUrl: serverUrl, taskIdentifier: task.taskIdentifier, freeze: false) else { - return - } - + guard let metadata = NCManageDatabase.sharedInstance.getMetadataInSessionFromFileName(fileName, serverUrl: serverUrl, taskIdentifier: task.taskIdentifier) else { return } guard let tableAccount = NCManageDatabase.sharedInstance.getAccount(predicate: NSPredicate(format: "account == %@", metadata.account)) else { return } if errorCode == 0 && ocId != nil { + let metadata = tableMetadata.init(value: metadata) + let ocIdTemp = metadata.ocId + CCUtility.moveFile(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId), toPath: CCUtility.getDirectoryProviderStorageOcId(ocId)) - NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) metadata.uploadDate = date ?? NSDate() metadata.etag = etag ?? "" @@ -418,8 +428,9 @@ import Alamofire metadata.deleteAssetLocalIdentifier = true; } - if let result = NCManageDatabase.sharedInstance.addMetadata(metadata) { metadata = result } - + NCManageDatabase.sharedInstance.addMetadata(metadata) + NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp)) + if CCUtility.getDisableLocalCacheAfterUpload() { CCUtility.removeFile(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId)) } else { @@ -462,154 +473,98 @@ import Alamofire } else { - NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, session: "", sessionError: errorDescription, sessionTaskIdentifier: 0, status: Int(k_metadataStatusUploadError)) + NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: Int(k_metadataStatusUploadError)) NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadedFile, userInfo: ["metadata":metadata, "errorCode":errorCode, "errorDescription":errorDescription]) - - if let result = NCManageDatabase.sharedInstance.addMetadata(metadata) { metadata = result } } + // Delete + self.uploadMetadata[fileName+serverUrl] = nil + NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["ocId":metadata.ocId, "serverUrl":metadata.serverUrl]) } } - //MARK: - Download / Upload - - @objc func verifyTransfer() { + @objc func verifyUploadZombie() { var session: URLSession? - // download - if let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "status == %d", Int(k_metadataStatusDownloading))) { - for metadata in metadatas { - guard let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView) else { continue } - let request = downloadRequest[fileNameLocalPath] - if request == nil { - metadata.session = "" - metadata.sessionError = "" - metadata.status = Int(k_metadataStatusNormal) - NCManageDatabase.sharedInstance.addMetadata(metadata) - - NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["ocId":metadata.ocId, "serverUrl":metadata.serverUrl]) - } - } - } - - // upload - if let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "session == %@ AND status == %d", NCCommunicationCommon.shared.sessionIdentifierUpload ,Int(k_metadataStatusUploading))) { - for metadata in metadatas { - guard let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView) else { continue } - let request = uploadRequest[fileNameLocalPath] - if request == nil { - CCUtility.removeFile(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId)) - NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) - - NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["serverUrl":metadata.serverUrl]) - } - } - } - // k_metadataStatusUploading (BACKGROUND) let sessionBackground = NCCommunicationCommon.shared.sessionIdentifierBackground let sessionBackgroundWWan = NCCommunicationCommon.shared.sessionIdentifierBackgroundWWan - if let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "(session == %@ OR session == %@) AND status == %d", sessionBackground, sessionBackgroundWWan, k_metadataStatusUploading)) { - - for metadata in metadatas { - - if metadata.session == NCCommunicationCommon.shared.sessionIdentifierBackground { - session = NCCommunicationBackground.shared.sessionManagerTransfer - } else if metadata.session == NCCommunicationCommon.shared.sessionIdentifierBackgroundWWan { - session = NCCommunicationBackground.shared.sessionManagerTransferWWan - } else if metadata.session == NCCommunicationCommon.shared.sessionIdentifierExtension { - session = NCCommunicationBackground.shared.sessionManagerTransferExtension + let sessionBackgroundExtension = NCCommunicationCommon.shared.sessionIdentifierExtension + var metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "(session == %@ OR session == %@ OR session == %@) AND status == %d", sessionBackground, sessionBackgroundWWan, sessionBackgroundExtension, k_metadataStatusUploading)) + for metadata in metadatas { + + if metadata.session == NCCommunicationCommon.shared.sessionIdentifierBackground { + session = NCCommunicationBackground.shared.sessionManagerTransfer + } else if metadata.session == NCCommunicationCommon.shared.sessionIdentifierBackgroundWWan { + session = NCCommunicationBackground.shared.sessionManagerTransferWWan + } else if metadata.session == NCCommunicationCommon.shared.sessionIdentifierExtension { + session = NCCommunicationBackground.shared.sessionManagerTransferExtension + } + + var findTask = false + + session?.getAllTasks(completionHandler: { (tasks) in + for task in tasks { + if task.taskIdentifier == metadata.sessionTaskIdentifier { + findTask = true + } } - var findTask = false - - session?.getAllTasks(completionHandler: { (tasks) in - for task in tasks { - if task.taskIdentifier == metadata.sessionTaskIdentifier { - findTask = true + if !findTask { + DispatchQueue.main.asyncAfter(deadline: .now() + 5) { + if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@ AND status == %d", metadata.ocId, k_metadataStatusUploading)) { + NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, session: NCCommunicationCommon.shared.sessionIdentifierBackground, sessionError: "", sessionSelector: nil, sessionTaskIdentifier: 0, status: Int(k_metadataStatusWaitUpload)) } } - - if !findTask { - DispatchQueue.main.asyncAfter(deadline: .now() + 5) { - if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@ AND status == %d", metadata.ocId, k_metadataStatusUploading)) { - - metadata.session = NCCommunicationCommon.shared.sessionIdentifierBackground - metadata.sessionError = "" - metadata.sessionTaskIdentifier = 0 - metadata.status = Int(k_metadataStatusWaitUpload) - - NCManageDatabase.sharedInstance.addMetadata(metadata) - } - } - } - }) - } + } + }) } + // verify k_metadataStatusInUpload (BACKGROUND) - if let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "(session == %@ OR session == %@) AND status == %d AND sessionTaskIdentifier == 0", sessionBackground, sessionBackgroundWWan, k_metadataStatusInUpload)) { - - for metadata in metadatas { - DispatchQueue.main.asyncAfter(deadline: .now() + 5) { - if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@ AND status == %d AND sessionTaskIdentifier == 0", metadata.ocId, k_metadataStatusInUpload)) { - - metadata.session = NCCommunicationCommon.shared.sessionIdentifierBackground - metadata.sessionError = "" - metadata.sessionTaskIdentifier = 0 - metadata.status = Int(k_metadataStatusWaitUpload) - - NCManageDatabase.sharedInstance.addMetadata(metadata) - } + metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "(session == %@ OR session == %@ OR session == %@) AND status == %d AND sessionTaskIdentifier == 0", sessionBackground, sessionBackgroundWWan, sessionBackgroundExtension, k_metadataStatusInUpload)) + for metadata in metadatas { + DispatchQueue.main.asyncAfter(deadline: .now() + 5) { + if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@ AND status == %d AND sessionTaskIdentifier == 0", metadata.ocId, k_metadataStatusInUpload)) { + NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, session: NCCommunicationCommon.shared.sessionIdentifierBackground, sessionError: "", sessionSelector: nil, sessionTaskIdentifier: 0, status: Int(k_metadataStatusWaitUpload)) } } } + } - + //MARK: - WebDav Read file, folder - @objc func readFolder(serverUrl: String, account: String, completion: @escaping (_ account: String, _ metadataFolder: tableMetadata?, _ metadatas: [tableMetadata]?, _ errorCode: Int, _ errorDescription: String)->()) { + @objc func readFolder(serverUrl: String, account: String, completion: @escaping (_ account: String, _ metadataFolder: tableMetadata?, _ metadatas: [tableMetadata]?, _ metadatasChanged: [tableMetadata]?, _ errorCode: Int, _ errorDescription: String)->()) { NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in - if errorCode == 0 && files != nil { + if errorCode == 0 { - NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files!, useMetadataFolder: true, account: account) { (metadataFolder, metadatasFolder, metadatas) in + NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: true, account: account) { (metadataFolder, metadatasFolder, metadatas) in - // Add directory - NCManageDatabase.sharedInstance.addDirectory(encrypted: metadataFolder.e2eEncrypted, favorite: metadataFolder.favorite, ocId: metadataFolder.ocId, fileId: metadataFolder.fileId, etag: metadataFolder.etag, permissions: metadataFolder.permissions, serverUrl: serverUrl, richWorkspace: metadataFolder.richWorkspace, account: account) + // Update directory + NCManageDatabase.sharedInstance.addDirectory(encrypted: metadataFolder.e2eEncrypted, favorite: metadataFolder.favorite, ocId: metadataFolder.ocId, fileId: metadataFolder.fileId, etag: metadataFolder.etag, permissions: metadataFolder.permissions, serverUrl: serverUrl, richWorkspace: metadataFolder.richWorkspace, account: metadataFolder.account) - // Add other directories + // Update sub directories for metadata in metadatasFolder { - let serverUrl = metadata.serverUrl + "/" + metadata.fileName - NCManageDatabase.sharedInstance.addDirectory(encrypted: metadata.e2eEncrypted, favorite: metadata.favorite, ocId: metadata.ocId, fileId: metadata.fileId, etag: nil, permissions: metadata.permissions, serverUrl: serverUrl, richWorkspace: metadata.richWorkspace, account: account) + let serverUrl = metadata.serverUrl + "/" + metadata.fileName + NCManageDatabase.sharedInstance.addDirectory(encrypted: metadata.e2eEncrypted, favorite: metadata.favorite, ocId: metadata.ocId, fileId: metadata.fileId, etag: nil, permissions: metadata.permissions, serverUrl: serverUrl, richWorkspace: metadata.richWorkspace, account: account) } - // Save status transfer metadata - let metadatasInDownload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", account, serverUrl, k_metadataStatusWaitDownload, k_metadataStatusInDownload, k_metadataStatusDownloading, k_metadataStatusDownloadError)) - - let metadatasInUpload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (status == %d OR status == %d OR status == %d OR status == %d)", account, serverUrl, k_metadataStatusWaitUpload, k_metadataStatusInUpload, k_metadataStatusUploading, k_metadataStatusUploadError)) - - // Delete metadata - NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, k_metadataStatusNormal)) - - // Add metadata - let metadataFolderInserted = NCManageDatabase.sharedInstance.addMetadata(metadataFolder) - let metadatasInserted = NCManageDatabase.sharedInstance.addMetadatas(metadatas) - - if metadatasInDownload != nil { - NCManageDatabase.sharedInstance.addMetadatas(metadatasInDownload!) - } - if metadatasInUpload != nil { - NCManageDatabase.sharedInstance.addMetadatas(metadatasInUpload!) + DispatchQueue.global().async { + let metadatasResult = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND status == %d", account, serverUrl, k_metadataStatusNormal)) + let metadatasChanged = NCManageDatabase.sharedInstance.updateMetadatas(metadatas, metadatasResult: metadatasResult) + if metadatasChanged.count > 0 { + NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["serverUrl":serverUrl]) + } + DispatchQueue.main.async { + completion(account, metadataFolder, metadatas, metadatasChanged, errorCode, "") + } } - - NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["serverUrl":serverUrl]) - - completion(account, metadataFolderInserted, metadatasInserted, errorCode, "") } } else { @@ -618,7 +573,7 @@ import Alamofire NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode) #endif - completion(account, nil, nil, errorCode, errorDescription) + completion(account, nil, nil, nil, errorCode, errorDescription) } } } @@ -627,9 +582,9 @@ import Alamofire NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in - if errorCode == 0 && files != nil { - if files?.count ?? 0 == 1 { - let file = files![0] + if errorCode == 0 { + if files.count == 1 { + let file = files[0] let isEncrypted = CCUtility.isFolderEncrypted(file.serverUrl, e2eEncrypted:file.e2eEncrypted, account: account) let metadata = NCManageDatabase.sharedInstance.convertNCFileToMetadata(file, isEncrypted: isEncrypted, account: account) completion(account, metadata, errorCode, "") @@ -637,7 +592,6 @@ import Alamofire completion(account, nil, errorCode, "") } } else { - completion(account, nil, errorCode, errorDescription) } } @@ -801,6 +755,36 @@ import Alamofire } } + @objc func listingFavoritescompletion(completion: @escaping (_ account: String, _ metadatas: [tableMetadata]?, _ errorCode: Int, _ errorDescription: String)->()) { + NCCommunication.shared.listingFavorites(showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, errorCode, errorDescription) in + + if errorCode == 0 { + NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: false, account: account) { (_, _, metadatas) in + // remove + let metadatasFavorite = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND favorite == true", account)) + for metadata in metadatasFavorite { + if metadatas.firstIndex(where: { $0.ocId == metadata.ocId }) == nil { + NCManageDatabase.sharedInstance.setMetadataFavorite(ocId: metadata.ocId, favorite: false) + } + } + #if !EXTENSION + for metadata in metadatas { + NCManageDatabase.sharedInstance.setMetadataFavorite(ocId: metadata.ocId, favorite: true) + if CCUtility.getFavoriteOffline() { + NCOperationQueue.shared.synchronizationMetadata(metadata, selector: selectorDownloadSynchronize) + } else { + NCOperationQueue.shared.synchronizationMetadata(metadata, selector: selectorSynchronize) + } + } + #endif + completion(account, metadatas, errorCode, errorDescription) + } + } else { + completion(account, nil, errorCode, errorDescription) + } + } + } + //MARK: - WebDav Rename @objc func renameMetadata(_ metadata: tableMetadata, fileNameNew: String, url: String, viewController: UIViewController?, completion: @escaping (_ errorCode: Int, _ errorDescription: String?)->()) { @@ -919,24 +903,24 @@ import Alamofire let serverUrlFileNameDestination = serverUrlTo + "/" + metadata.fileName NCCommunication.shared.moveFileOrFolder(serverUrlFileNameSource: serverUrlFileNameSource, serverUrlFileNameDestination: serverUrlFileNameDestination, overwrite: overwrite) { (account, errorCode, errorDescription) in - - var metadataNew = tableMetadata() - + if errorCode == 0 { if metadata.directory { NCManageDatabase.sharedInstance.deleteDirectoryAndSubDirectory(serverUrl: CCUtility.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName), account: account) } - if let metadataMove = NCManageDatabase.sharedInstance.moveMetadata(ocId: metadata.ocId, serverUrlTo: serverUrlTo) { - metadataNew = metadataMove - } + NCManageDatabase.sharedInstance.moveMetadata(ocId: metadata.ocId, serverUrlTo: serverUrlTo) + guard let metadataNew = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) else { return } NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["serverUrl":metadata.serverUrl]) NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["serverUrl":serverUrlTo]) + + self.NotificationPost(name: k_notificationCenter_moveFile, userInfo: ["metadata": metadata, "metadataNew": metadataNew, "errorCode": errorCode], errorDescription: errorDescription, completion: completion) + + } else { + self.NotificationPost(name: k_notificationCenter_moveFile, userInfo: ["metadata": metadata, "errorCode": errorCode], errorDescription: errorDescription, completion: completion) } - - self.NotificationPost(name: k_notificationCenter_moveFile, userInfo: ["metadata": metadata, "metadataNew": metadataNew, "errorCode": errorCode], errorDescription: errorDescription, completion: completion) } } diff --git a/iOSClient/Networking/NCNetworkingAutoUpload.swift b/iOSClient/Networking/NCNetworkingAutoUpload.swift index 4d8c7d44c..28e602f23 100644 --- a/iOSClient/Networking/NCNetworkingAutoUpload.swift +++ b/iOSClient/Networking/NCNetworkingAutoUpload.swift @@ -53,13 +53,12 @@ class NCNetworkingAutoUpload: NSObject { timerProcess?.invalidate() - if let metadatasUpload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "status == %d OR status == %d", k_metadataStatusInUpload, k_metadataStatusUploading), freeze: true) { - counterUpload = metadatasUpload.count - for metadata in metadatasUpload { - sizeUpload = sizeUpload + Int(metadata.size) - } + let metadatasUpload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "status == %d OR status == %d", k_metadataStatusInUpload, k_metadataStatusUploading)) + counterUpload = metadatasUpload.count + for metadata in metadatasUpload { + sizeUpload = sizeUpload + Int(metadata.size) } - + debugPrint("[LOG] PROCESS-AUTO-UPLOAD \(counterUpload)") // ------------------------- <selector Upload> ------------------------- @@ -68,7 +67,7 @@ class NCNetworkingAutoUpload: NSObject { if sizeUpload > k_maxSizeOperationUpload { break } let predicate = NSPredicate(format: "sessionSelector == %@ AND status == %d", selectorUploadFile, k_metadataStatusWaitUpload) - if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: predicate, sorted: "date", ascending: true, freeze: true) { + if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: predicate, sorted: "date", ascending: true) { if CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account) { if UIApplication.shared.applicationState == .background { break } maxConcurrentOperationUpload = 1 @@ -95,7 +94,7 @@ class NCNetworkingAutoUpload: NSObject { predicate = NSPredicate(format: "sessionSelector == %@ AND status == %d", selectorUploadAutoUpload, k_metadataStatusWaitUpload) } - if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: predicate, sorted: "date", ascending: true, freeze: true) { + if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: predicate, sorted: "date", ascending: true) { if CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account) { if UIApplication.shared.applicationState == .background { break } maxConcurrentOperationUpload = 1 @@ -112,10 +111,9 @@ class NCNetworkingAutoUpload: NSObject { // ------------------------- <selector Auto Upload All> ---------------------- // Verify num error k_maxErrorAutoUploadAll after STOP (100) - if let metadatasInError = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "sessionSelector == %@ AND status == %d", selectorUploadAutoUploadAll, k_metadataStatusUploadError), freeze: true) { - if metadatasInError.count >= k_maxErrorAutoUploadAll { - NCContentPresenter.shared.messageNotification("_error_", description: "_too_errors_automatic_all_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError)) - } + let metadatasInError = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "sessionSelector == %@ AND status == %d", selectorUploadAutoUploadAll, k_metadataStatusUploadError)) + if metadatasInError.count >= k_maxErrorAutoUploadAll { + NCContentPresenter.shared.messageNotification("_error_", description: "_too_errors_automatic_all_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError)) } else { while counterUpload < maxConcurrentOperationUpload { if sizeUpload > k_maxSizeOperationUpload { break } @@ -127,7 +125,7 @@ class NCNetworkingAutoUpload: NSObject { predicate = NSPredicate(format: "sessionSelector == %@ AND status == %d", selectorUploadAutoUploadAll, k_metadataStatusWaitUpload) } - if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: predicate, sorted: "date", ascending: true, freeze: true) { + if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: predicate, sorted: "date", ascending: true) { if CCUtility.isFolderEncrypted(metadata.serverUrl, e2eEncrypted: metadata.e2eEncrypted, account: metadata.account) { if UIApplication.shared.applicationState == .background { break } maxConcurrentOperationUpload = 1 @@ -144,19 +142,22 @@ class NCNetworkingAutoUpload: NSObject { // No upload available ? --> Retry Upload in Error if counterUpload == 0 { - if let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "status == %d", selectorUploadAutoUploadAll, k_metadataStatusUploadError), freeze: true) { - for metadata in metadatas { - NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, session: NCCommunicationCommon.shared.sessionIdentifierBackground, sessionError: "", sessionTaskIdentifier: 0 ,status: Int(k_metadataStatusInUpload)) - } + let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "status == %d", k_metadataStatusUploadError)) + for metadata in metadatas { + NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, session: NCCommunicationCommon.shared.sessionIdentifierBackground, sessionError: "", sessionTaskIdentifier: 0 ,status: Int(k_metadataStatusWaitUpload)) } } // verify delete Asset Local Identifiers in auto upload (DELETE Photos album) if (counterUpload == 0 && appDelegate.passcodeViewController == nil) { - NCUtility.sharedInstance.deleteAssetLocalIdentifiers(account: appDelegate.activeAccount, sessionSelector: selectorUploadAutoUpload) + NCUtility.sharedInstance.deleteAssetLocalIdentifiers(account: appDelegate.activeAccount, sessionSelector: selectorUploadAutoUpload) { + + self.timerProcess = Timer.scheduledTimer(timeInterval: TimeInterval(k_timerAutoUpload), target: self, selector: #selector(self.process), userInfo: nil, repeats: true) + } + } else { + + timerProcess = Timer.scheduledTimer(timeInterval: TimeInterval(k_timerAutoUpload), target: self, selector: #selector(process), userInfo: nil, repeats: true) } - - timerProcess = Timer.scheduledTimer(timeInterval: TimeInterval(k_timerAutoUpload), target: self, selector: #selector(process), userInfo: nil, repeats: true) } } diff --git a/iOSClient/Networking/NCNetworkingE2EE.swift b/iOSClient/Networking/NCNetworkingE2EE.swift index 9603c567e..e0add4fff 100644 --- a/iOSClient/Networking/NCNetworkingE2EE.swift +++ b/iOSClient/Networking/NCNetworkingE2EE.swift @@ -54,60 +54,43 @@ import Alamofire NCCommunication.shared.createFolder(fileNameFolderUrl, addCustomHeaders: ["e2e-token" : e2eToken!]) { (account, ocId, date, errorCode, errorDescription) in if errorCode == 0 { - - NCNetworking.shared.readFile(serverUrlFileName: fileNameFolderUrl, account: account) { (account, metadataFolder, errorCode, errorDescription) in + NCCommunication.shared.markE2EEFolder(fileId: ocId!, delete: false) { (account, errorCode, errorDescription) in if errorCode == 0 { + + let object = tableE2eEncryption() + + NCEndToEndEncryption.sharedManager()?.encryptkey(&key, initializationVector: &initializationVector) - // Add Metadata - metadataFolder?.fileNameView = fileNameFolder - metadataFolder?.e2eEncrypted = true - NCManageDatabase.sharedInstance.addMetadata(metadataFolder!) - // Add folder - NCManageDatabase.sharedInstance.addDirectory(encrypted: true, favorite: metadataFolder!.favorite, ocId: metadataFolder!.ocId, fileId: metadataFolder!.fileId, etag: nil, permissions: metadataFolder!.permissions, serverUrl: fileNameFolderUrl, richWorkspace: metadataFolder!.richWorkspace, account: account) - - NCCommunication.shared.markE2EEFolder(fileId: metadataFolder!.fileId, delete: false) { (account, errorCode, errorDescription) in - if errorCode == 0 { - - let object = tableE2eEncryption() - - NCEndToEndEncryption.sharedManager()?.encryptkey(&key, initializationVector: &initializationVector) - - object.account = account - object.authenticationTag = nil - object.fileName = fileNameFolder - object.fileNameIdentifier = fileNameIdentifier - object.fileNamePath = "" - object.key = key! as String - object.initializationVector = initializationVector! as String - - if let result = NCManageDatabase.sharedInstance.getE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) { - object.metadataKey = result.metadataKey - object.metadataKeyIndex = result.metadataKeyIndex - } else { - object.metadataKey = (NCEndToEndEncryption.sharedManager()?.generateKey(16)?.base64EncodedString(options: []))! as String // AES_KEY_128_LENGTH - object.metadataKeyIndex = 0 - } - object.mimeType = "httpd/unix-directory" - object.serverUrl = serverUrl - if let e2eeApiVersion = NCManageDatabase.sharedInstance.getCapabilitiesServerString(account: account, elements: NCElementsJSON.shared.capabilitiesE2EEApiVersion) { - object.version = Int(e2eeApiVersion) ?? 1 - } else { - object.version = 1 - } - - let _ = NCManageDatabase.sharedInstance.addE2eEncryption(object) - - self.sendE2EMetadata(account: account, serverUrl: serverUrl, fileNameRename: nil, fileNameNewRename: nil, deleteE2eEncryption: nil, url: url) { (e2eToken, errorCode, errorDescription) in - self.NotificationPost(name: k_notificationCenter_createFolder, serverUrl: serverUrl, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": errorCode], errorDescription: errorDescription, completion: completion) - } - } else { - self.NotificationPost(name: k_notificationCenter_createFolder, serverUrl: serverUrl, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": errorCode], errorDescription: errorDescription, completion: completion) - } + object.account = account + object.authenticationTag = nil + object.fileName = fileNameFolder + object.fileNameIdentifier = fileNameIdentifier + object.fileNamePath = "" + object.key = key! as String + object.initializationVector = initializationVector! as String + + if let result = NCManageDatabase.sharedInstance.getE2eEncryption(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) { + object.metadataKey = result.metadataKey + object.metadataKeyIndex = result.metadataKeyIndex + } else { + object.metadataKey = (NCEndToEndEncryption.sharedManager()?.generateKey(16)?.base64EncodedString(options: []))! as String // AES_KEY_128_LENGTH + object.metadataKeyIndex = 0 } + object.mimeType = "httpd/unix-directory" + object.serverUrl = serverUrl + object.version = 1 + + let _ = NCManageDatabase.sharedInstance.addE2eEncryption(object) + + self.sendE2EMetadata(account: account, serverUrl: serverUrl, fileNameRename: nil, fileNameNewRename: nil, deleteE2eEncryption: nil, url: url) { (e2eToken, errorCode, errorDescription) in + self.NotificationPost(name: k_notificationCenter_createFolder, serverUrl: serverUrl, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": errorCode], errorDescription: errorDescription, completion: completion) + } + } else { self.NotificationPost(name: k_notificationCenter_createFolder, serverUrl: serverUrl, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": errorCode], errorDescription: errorDescription, completion: completion) } } + } else { self.NotificationPost(name: k_notificationCenter_createFolder, serverUrl: serverUrl, userInfo: ["fileName": fileName, "serverUrl": serverUrl, "errorCode": errorCode], errorDescription: errorDescription, completion: completion) } @@ -178,14 +161,19 @@ import Alamofire func upload(metadata: tableMetadata, account: tableAccount, completion: @escaping (_ errorCode: Int, _ errorDescription: String)->()) { - var metadata = metadata let objectE2eEncryption = tableE2eEncryption() var key: NSString?, initializationVector: NSString?, authenticationTag: NSString? - + let ocIdTemp = metadata.ocId let serverUrl = metadata.serverUrl - - metadata.fileName = CCUtility.generateRandomIdentifier()! - metadata.e2eEncrypted = true + + // Update metadata + let metadataUpdate = tableMetadata.init(value: metadata) + metadataUpdate.fileName = CCUtility.generateRandomIdentifier()! + metadataUpdate.e2eEncrypted = true + metadataUpdate.status = Int(k_metadataStatusInUpload) + metadataUpdate.session = NCCommunicationCommon.shared.sessionIdentifierUpload + metadataUpdate.sessionError = "" + NCManageDatabase.sharedInstance.addMetadata(metadataUpdate) let fileNameLocalPath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileName)! let serverUrlFileName = serverUrl + "/" + metadata.fileName @@ -216,9 +204,7 @@ import Alamofire objectE2eEncryption.initializationVector = initializationVector! as String objectE2eEncryption.mimeType = metadata.contentType objectE2eEncryption.serverUrl = serverUrl - - let e2eeApiVersion = NCManageDatabase.sharedInstance.getCapabilitiesServerString(account: metadata.account, elements: NCElementsJSON.shared.capabilitiesE2EEApiVersion)! - objectE2eEncryption.version = Int(e2eeApiVersion) ?? 1 + objectE2eEncryption.version = 1 if NCManageDatabase.sharedInstance.addE2eEncryption(objectE2eEncryption) == false { NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadedFile, userInfo: ["metadata":metadata, "errorCode":k_CCErrorInternalError, "errorDescription":"_e2e_error_create_encrypted_"]) @@ -226,22 +212,19 @@ import Alamofire return } + guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp)) else { return } + NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["ocId":metadata.ocId, "serverUrl":metadata.serverUrl]) + NCNetworkingE2EE.shared.sendE2EMetadata(account: metadata.account, serverUrl: serverUrl, fileNameRename: nil, fileNameNewRename: nil, deleteE2eEncryption: nil, url: account.url, upload: true) { (e2eToken, errorCode, errorDescription) in if errorCode == 0 && e2eToken != nil { - // Start Upload file - metadata.status = Int(k_metadataStatusInUpload) - metadata.session = NCCommunicationCommon.shared.sessionIdentifierUpload - if let result = NCManageDatabase.sharedInstance.addMetadata(metadata) { metadata = result } - NotificationCenter.default.postOnMainThread(name: k_notificationCenter_reloadDataSource, userInfo: ["ocId":metadata.ocId, "serverUrl":metadata.serverUrl]) NCCommunication.shared.upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, dateCreationFile: metadata.date as Date, dateModificationFile: metadata.date as Date, addCustomHeaders: ["e2e-token":e2eToken!], requestHandler: { (request) in NCNetworking.shared.uploadRequest[fileNameLocalPath] = request - metadata.status = Int(k_metadataStatusUploading) - if let result = NCManageDatabase.sharedInstance.addMetadata(metadata) { metadata = result } + NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: nil, sessionSelector: nil, sessionTaskIdentifier: nil, status: Int(k_metadataStatusUploading)) NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadFileStart, userInfo: ["ocId":metadata.ocId, "serverUrl":serverUrl, "account": metadata.account]) @@ -252,16 +235,20 @@ import Alamofire }) { (account, ocId, etag, date, size, error, errorCode, errorDescription) in NCNetworking.shared.uploadRequest[fileNameLocalPath] = nil - + guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) else { return } + if error?.isExplicitlyCancelledError ?? false { CCUtility.removeFile(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId)) NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) } else if errorCode == 0 && ocId != nil { - + + guard let metadataTemp = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) else { return } + let metadata = tableMetadata.init(value: metadataTemp) + + CCUtility.moveFile(atPath: CCUtility.getDirectoryProviderStorageOcId(metadata.ocId), toPath: CCUtility.getDirectoryProviderStorageOcId(ocId)) - NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)) metadata.date = date ?? NSDate() metadata.etag = etag ?? "" @@ -269,10 +256,12 @@ import Alamofire metadata.session = "" metadata.sessionError = "" + metadata.sessionTaskIdentifier = 0 metadata.status = Int(k_metadataStatusNormal) - + + NCManageDatabase.sharedInstance.addMetadata(metadata) + NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp)) NCManageDatabase.sharedInstance.addLocalFile(metadata: metadata) - if let result = NCManageDatabase.sharedInstance.addMetadata(metadata) { metadata = result } //CCGraphics.createNewImage(from: metadata.fileNameView, ocId: metadata.ocId, filterGrayScale: false, typeFile: metadata.typeFile, writeImage: true) @@ -295,11 +284,7 @@ import Alamofire } else { - metadata.session = "" - metadata.sessionError = errorDescription - metadata.status = Int(k_metadataStatusUploadError) - - if let result = NCManageDatabase.sharedInstance.addMetadata(metadata) { metadata = result } + NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: Int(k_metadataStatusUploadError)) NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadedFile, userInfo: ["metadata":metadata, "errorCode":errorCode, "errorDescription":errorDescription]) } @@ -313,7 +298,11 @@ import Alamofire } else { - NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadedFile, userInfo: ["metadata":metadata, "errorCode":errorCode, "errorDescription":errorDescription ?? ""]) + if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", ocIdTemp)) { + NCManageDatabase.sharedInstance.setMetadataSession(ocId: metadata.ocId, session: nil, sessionError: errorDescription, sessionTaskIdentifier: 0, status: Int(k_metadataStatusUploadError)) + + NotificationCenter.default.postOnMainThread(name: k_notificationCenter_uploadedFile, userInfo: ["metadata":metadata, "errorCode":errorCode, "errorDescription":errorDescription ?? ""]) + } completion(errorCode, errorDescription ?? "") } @@ -335,7 +324,7 @@ import Alamofire e2eToken = tableLock.e2eToken } - NCCommunication.shared.lockE2EEFolder(fileId: directory.fileId, e2eToken: e2eToken, delete: false) { (account, e2eToken, errorCode, errorDescription) in + NCCommunication.shared.lockE2EEFolder(fileId: directory.fileId, e2eToken: e2eToken, method: "POST") { (account, e2eToken, errorCode, errorDescription) in if errorCode == 0 && e2eToken != nil { NCManageDatabase.sharedInstance.setE2ETokenLock(serverUrl: serverUrl, fileId: directory.fileId, e2eToken: e2eToken!) } @@ -356,7 +345,7 @@ import Alamofire e2eToken = tableLock.e2eToken } - NCCommunication.shared.lockE2EEFolder(fileId: directory.fileId, e2eToken: e2eToken, delete: true) { (account, e2eToken, errorCode, errorDescription) in + NCCommunication.shared.lockE2EEFolder(fileId: directory.fileId, e2eToken: e2eToken, method: "DELETE") { (account, e2eToken, errorCode, errorDescription) in if errorCode == 0 { NCManageDatabase.sharedInstance.deteleE2ETokenLock(serverUrl: serverUrl) } @@ -395,6 +384,8 @@ import Alamofire let tableE2eEncryption = NCManageDatabase.sharedInstance.getE2eEncryptions(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", account, serverUrl)) if tableE2eEncryption != nil { e2eMetadataNew = NCEndToEndMetadata.sharedInstance.encoderMetadata(tableE2eEncryption!, privateKey: CCUtility.getEndToEndPrivateKey(account), serverUrl: serverUrl) + } else { + method = "DELETE" } NCCommunication.shared.putE2EEMetadata(fileId: directory!.fileId, e2eToken: e2eToken!, e2eMetadata: e2eMetadataNew, method: method) { (account, e2eMetadata, errorCode, errorDescription) in @@ -422,7 +413,7 @@ import Alamofire // unlock if let tableLock = NCManageDatabase.sharedInstance.getE2ETokenLock(serverUrl: serverUrl) { - NCCommunication.shared.lockE2EEFolder(fileId: tableLock.fileId, e2eToken: tableLock.e2eToken, delete: true) { (_, _, _, _) in } + NCCommunication.shared.lockE2EEFolder(fileId: tableLock.fileId, e2eToken: tableLock.e2eToken, method: "DELETE") { (_, _, _, _) in } } if errorDescription == nil { userInfo["errorDescription"] = "" } diff --git a/iOSClient/Networking/NCNetworkingNotificationCenter.swift b/iOSClient/Networking/NCNetworkingNotificationCenter.swift index f147eaa3b..501e5c17e 100644 --- a/iOSClient/Networking/NCNetworkingNotificationCenter.swift +++ b/iOSClient/Networking/NCNetworkingNotificationCenter.swift @@ -86,7 +86,7 @@ import Foundation if metadata.typeFile == k_metadataTypeFile_imagemeter { if !IMUtility.shared.IMUnzip(metadata: metadata) { - NCContentPresenter.shared.messageNotification("_error_", description: "Bundle imagemeter error. 🤷♂️", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0) + NCContentPresenter.shared.messageNotification("_error_", description: "Bundle imagemeter error. 🤷♂️", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError)) return } diff --git a/iOSClient/Networking/NCOperationQueue.swift b/iOSClient/Networking/NCOperationQueue.swift index fa67c5483..3775e12f9 100644 --- a/iOSClient/Networking/NCOperationQueue.swift +++ b/iOSClient/Networking/NCOperationQueue.swift @@ -33,7 +33,7 @@ import NCCommunication }() private var downloadQueue = Queuer(name: "downloadQueue", maxConcurrentOperationCount: 5, qualityOfService: .default) - private let readFolderSyncQueue = Queuer(name: "readFolderSyncQueue", maxConcurrentOperationCount: 1, qualityOfService: .default) + private let synchronizationQueue = Queuer(name: "synchronizationQueue", maxConcurrentOperationCount: 1, qualityOfService: .default) private let createFolderQueue = Queuer(name: "createFolderQueue", maxConcurrentOperationCount: 1, qualityOfService: .default) private let downloadThumbnailQueue = Queuer(name: "downloadThumbnailQueue", maxConcurrentOperationCount: 10, qualityOfService: .default) private let readFileForMediaQueue = Queuer(name: "readFileForMediaQueue", maxConcurrentOperationCount: 10, qualityOfService: .default) @@ -42,7 +42,7 @@ import NCCommunication @objc func cancelAllQueue() { downloadCancelAll() - readFolderSyncCancelAll() + synchronizationCancelAll() createFolderCancelAll() downloadThumbnailCancelAll() readFileForMediaCancelAll() @@ -60,13 +60,13 @@ import NCCommunication return downloadQueue.operationCount } - // Read Folder Synchronize + // Synchronization - @objc func readFolderSync(serverUrl: String, selector: String ,account: String) { - readFolderSyncQueue.addOperation(NCOperationReadFolderSync.init(serverUrl: serverUrl, selector: selector, account: account)) + @objc func synchronizationMetadata(_ metadata: tableMetadata, selector: String) { + synchronizationQueue.addOperation(NCOperationSynchronization.init(metadata: metadata, selector: selector)) } - @objc func readFolderSyncCancelAll() { - readFolderSyncQueue.cancelAll() + @objc func synchronizationCancelAll() { + synchronizationQueue.cancelAll() } // Create Folder @@ -160,34 +160,61 @@ class NCOperationDownload: ConcurrentOperation { //MARK: - -class NCOperationReadFolderSync: ConcurrentOperation { +class NCOperationSynchronization: ConcurrentOperation { - private var serverUrl: String + private var metadata: tableMetadata private var selector: String - private var account: String - init(serverUrl: String, selector: String, account: String) { - self.serverUrl = serverUrl + init(metadata: tableMetadata, selector: String) { + self.metadata = metadata self.selector = selector - self.account = account } override func start() { if isCancelled { self.finish() } else { - NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in - if errorCode == 0 && files != nil { - NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files!, useMetadataFolder: true, account: account) { (metadataFolder, metadatasFolder, metadatas) in - - if metadatas.count > 0 { - CCSynchronize.shared()?.readFolder(withAccount: account, serverUrl: self.serverUrl, metadataFolder: metadataFolder, metadatas: metadatas, selector: self.selector) + var depth: String = "" + var serverUrlFileName: String = "" + var predicate = NSPredicate() + var download = false + var useMetadataFolder = false + if metadata.directory { + depth = "infinity" + useMetadataFolder = true + serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName + predicate = NSPredicate(format: "account == %@ AND serverUrl BEGINSWITH %@ AND status == %d", metadata.account, serverUrlFileName, k_metadataStatusNormal) + } else { + depth = "0" + useMetadataFolder = false + serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName + predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@ AND status == %d", metadata.account, metadata.serverUrl, metadata.fileName, k_metadataStatusNormal) + } + if selector == selectorDownloadSynchronize { + download = true + } + + NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: depth, showHiddenFiles: CCUtility.getShowHiddenFiles()) { (account, files, responseData, errorCode, errorDescription) in + DispatchQueue.global().async { + if errorCode == 0 { + NCManageDatabase.sharedInstance.convertNCCommunicationFilesToMetadatas(files, useMetadataFolder: useMetadataFolder, account: account) { (metadataFolder, metadatasFolder, metadatas) in + if metadatas.count > 0 { + let metadatasResult = NCManageDatabase.sharedInstance.getMetadatas(predicate: predicate) + let metadatasChanged = NCManageDatabase.sharedInstance.updateMetadatas(metadatas, metadatasResult: metadatasResult, withVerifyLocal: download) + if download { + for metadata in metadatasChanged { + if metadata.directory == false { + NCNetworking.shared.download(metadata: metadata, selector: selectorDownloadSynchronize) { (_) in } + } + } + } + } } + } else if errorCode == 404 && self.metadata.directory { + NCManageDatabase.sharedInstance.deleteDirectoryAndSubDirectory(serverUrl: self.metadata.serverUrl, account: self.metadata.account) } - } else if errorCode == 404 { - NCManageDatabase.sharedInstance.deleteDirectoryAndSubDirectory(serverUrl: self.serverUrl, account: account) + self.finish() } - self.finish() } } } @@ -309,26 +336,25 @@ class NCOperationReadFileForMediaQueue: ConcurrentOperation { """ NCCommunication.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0", requestBody: requestBody.data(using: .utf8)) { (account, files, responseData, errorCode, errorDescription) in - if errorCode == 0 && files != nil { - if let file = files?[0] { - let metadata = tableMetadata.init(value: self.metadata) - var modify = false - if metadata.hasPreview != file.hasPreview { - metadata.hasPreview = file.hasPreview - modify = true - } - if file.creationDate != nil && metadata.creationDate != file.creationDate { - metadata.creationDate = file.creationDate! - modify = true - } - if file.uploadDate != nil && metadata.uploadDate != file.uploadDate { - metadata.uploadDate = file.uploadDate! - modify = true - } - if modify { - NCManageDatabase.sharedInstance.addMetadata(metadata) - NCOperationQueue.shared.reloadDataSourceMedia() - } + if errorCode == 0 && files.count > 0 { + let file = files[0] + let metadata = tableMetadata.init(value: self.metadata) + var modify = false + if metadata.hasPreview != file.hasPreview { + metadata.hasPreview = file.hasPreview + modify = true + } + if file.creationDate != nil && metadata.creationDate != file.creationDate { + metadata.creationDate = file.creationDate! + modify = true + } + if file.uploadDate != nil && metadata.uploadDate != file.uploadDate { + metadata.uploadDate = file.uploadDate! + modify = true + } + if modify { + NCManageDatabase.sharedInstance.addMetadata(metadata) + NCOperationQueue.shared.reloadDataSourceMedia() } } else if errorCode == 404 { NCManageDatabase.sharedInstance.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", self.metadata.ocId)) diff --git a/iOSClient/Networking/NCService.swift b/iOSClient/Networking/NCService.swift index c005e76f3..b2f7ac594 100644 --- a/iOSClient/Networking/NCService.swift +++ b/iOSClient/Networking/NCService.swift @@ -68,25 +68,29 @@ class NCService: NSObject { let url = tableAccount.url self.appDelegate.settingActiveAccount(tableAccount.account, activeUrl: tableAccount.url, activeUser: tableAccount.user, activeUserID: tableAccount.userID, activePassword: CCUtility.getPassword(tableAccount.account)) - + + // Synchronize favorite --- + NCNetworking.shared.listingFavoritescompletion { (_, _, _, _) in } + // Synchronize Offline --- let directories = NCManageDatabase.sharedInstance.getTablesDirectory(predicate: NSPredicate(format: "account == %@ AND offline == true", tableAccount.account), sorted: "serverUrl", ascending: true) if (directories != nil) { for directory: tableDirectory in directories! { - CCSynchronize.shared()?.readFolder(directory.serverUrl, selector: selectorReadFolderWithDownload, account: tableAccount.account) + guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", directory.ocId)) else { + continue + } + NCOperationQueue.shared.synchronizationMetadata(metadata, selector: selectorDownloadSynchronize) } } let files = NCManageDatabase.sharedInstance.getTableLocalFiles(predicate: NSPredicate(format: "account == %@ AND offline == true", tableAccount.account), sorted: "fileName", ascending: true) - if (files != nil) { - for file: tableLocalFile in files! { - guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", file.ocId)) else { - continue - } - CCSynchronize.shared()?.readFile(metadata.ocId, fileName: metadata.fileName, serverUrl: metadata.serverUrl, selector: selectorReadFileWithDownload, account: tableAccount.account) + for file: tableLocalFile in files { + guard let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "ocId == %@", file.ocId)) else { + continue } + NCOperationQueue.shared.synchronizationMetadata(metadata, selector: selectorDownloadSynchronize) } - + let avatarUrl = "\(self.appDelegate.activeUrl!)/index.php/avatar/\(self.appDelegate.activeUser!)/\(k_avatar_size)".addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)! let fileNamePath = CCUtility.getDirectoryUserData() + "/" + CCUtility.getStringUser(user, activeUrl: url) + "-" + self.appDelegate.activeUser + ".png" @@ -175,7 +179,7 @@ class NCService: NSObject { } } - let isExternalSitesServerEnabled = NCManageDatabase.sharedInstance.getCapabilitiesServerBool(account: account, elements: NCElementsJSON.shared.capabilitiesExternalSitesExists, exists: true) + let isExternalSitesServerEnabled = NCManageDatabase.sharedInstance.getCapabilitiesServerBool(account: account, elements: NCElementsJSON.shared.capabilitiesExternalSitesExists, exists: false) if (isExternalSitesServerEnabled) { NCCommunication.shared.getExternalSite() { (account, externalSites, errorCode, errorDescription) in if errorCode == 0 && account == self.appDelegate.activeAccount { diff --git a/iOSClient/Nextcloud-Bridging-Header.h b/iOSClient/Nextcloud-Bridging-Header.h index be4867ea8..9791050cb 100644 --- a/iOSClient/Nextcloud-Bridging-Header.h +++ b/iOSClient/Nextcloud-Bridging-Header.h @@ -8,5 +8,4 @@ #import "NCAutoUpload.h" #import "NCEndToEndEncryption.h" #import "NYMnemonic.h" -#import "CCSynchronize.h" #import "PKStopDownloadButton.h" diff --git a/iOSClient/Offline/NCOffline.swift b/iOSClient/Offline/NCOffline.swift index 28384a245..c0dd43c58 100644 --- a/iOSClient/Offline/NCOffline.swift +++ b/iOSClient/Offline/NCOffline.swift @@ -671,23 +671,19 @@ extension NCOffline { } } - if let files = NCManageDatabase.sharedInstance.getTableLocalFiles(predicate: NSPredicate(format: "account == %@ AND offline == true", appDelegate.activeAccount), sorted: "fileName", ascending: true) { - for file: tableLocalFile in files { - ocIds.append(file.ocId) - } + let files = NCManageDatabase.sharedInstance.getTableLocalFiles(predicate: NSPredicate(format: "account == %@ AND offline == true", appDelegate.activeAccount), sorted: "fileName", ascending: true) + for file: tableLocalFile in files { + ocIds.append(file.ocId) } - if let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND ocId IN %@", appDelegate.activeAccount, ocIds)) { - - sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: true, sorted: datasourceSorted, ascending: datasourceAscending, activeAccount: appDelegate.activeAccount) - } + let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND ocId IN %@", appDelegate.activeAccount, ocIds)) + sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: true, sorted: datasourceSorted, ascending: datasourceAscending, activeAccount: appDelegate.activeAccount) } else { - if let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.activeAccount, serverUrl)) { - - sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: true, sorted: datasourceSorted, ascending: datasourceAscending, activeAccount: appDelegate.activeAccount) - } + let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", appDelegate.activeAccount, serverUrl)) + sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: true, sorted: datasourceSorted, ascending: datasourceAscending, activeAccount: appDelegate.activeAccount) + } self.refreshControl.endRefreshing() diff --git a/iOSClient/RichWorkspace/NCRichWorkspace.xib b/iOSClient/RichWorkspace/NCRichWorkspace.xib index 510cbbbd6..0e77410aa 100644 --- a/iOSClient/RichWorkspace/NCRichWorkspace.xib +++ b/iOSClient/RichWorkspace/NCRichWorkspace.xib @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <device id="retina5_5" orientation="portrait" appearance="light"/> <dependencies> <deployment version="4368" identifier="iOS"/> @@ -48,9 +48,8 @@ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="orF-i7-sVP"> <rect key="frame" x="0.0" y="40.666666666666686" width="414" height="695.33333333333326"/> <subviews> - <textView clipsSubviews="YES" multipleTouchEnabled="YES" userInteractionEnabled="NO" contentMode="scaleToFill" fixedFrame="YES" editable="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="wri-16-tQY"> - <rect key="frame" x="8" y="8" width="304" height="379"/> - <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> + <textView clipsSubviews="YES" multipleTouchEnabled="YES" userInteractionEnabled="NO" contentMode="scaleToFill" editable="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="wri-16-tQY"> + <rect key="frame" x="10" y="0.0" width="394" height="695.33333333333337"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="textColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/> <fontDescription key="fontDescription" type="system" pointSize="14"/> @@ -58,6 +57,12 @@ </textView> </subviews> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> + <constraints> + <constraint firstItem="wri-16-tQY" firstAttribute="top" secondItem="orF-i7-sVP" secondAttribute="top" id="7js-7b-K16"/> + <constraint firstAttribute="bottom" secondItem="wri-16-tQY" secondAttribute="bottom" id="a18-oE-B43"/> + <constraint firstAttribute="trailing" secondItem="wri-16-tQY" secondAttribute="trailing" constant="10" id="fLE-9r-zk7"/> + <constraint firstItem="wri-16-tQY" firstAttribute="leading" secondItem="orF-i7-sVP" secondAttribute="leading" constant="10" id="sHh-SV-ESA"/> + </constraints> </view> </subviews> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> diff --git a/iOSClient/RichWorkspace/NCRichWorkspaceCommon.swift b/iOSClient/RichWorkspace/NCRichWorkspaceCommon.swift index 9fb1a3461..61d9493eb 100644 --- a/iOSClient/RichWorkspace/NCRichWorkspaceCommon.swift +++ b/iOSClient/RichWorkspace/NCRichWorkspaceCommon.swift @@ -31,7 +31,7 @@ import NCCommunication @objc func createViewerNextcloudText(serverUrl: String,viewController: UIViewController) { if !NCCommunication.shared.isNetworkReachable() { - NCContentPresenter.shared.messageNotification("_error_", description: "_go_online_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0) + NCContentPresenter.shared.messageNotification("_error_", description: "_go_online_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true) return; } @@ -64,7 +64,7 @@ import NCCommunication if !NCCommunication.shared.isNetworkReachable() { - NCContentPresenter.shared.messageNotification("_error_", description: "_go_online_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0) + NCContentPresenter.shared.messageNotification("_error_", description: "_go_online_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true) return; } diff --git a/iOSClient/Security/NCEndToEndEncryption.m b/iOSClient/Security/NCEndToEndEncryption.m index 78dd83d96..7523fd73e 100644 --- a/iOSClient/Security/NCEndToEndEncryption.m +++ b/iOSClient/Security/NCEndToEndEncryption.m @@ -31,7 +31,7 @@ #define addName(field, value) X509_NAME_add_entry_by_txt(name, field, MBSTRING_ASC, (unsigned char *)value, -1, -1, 0); NSLog(@"%s: %s", field, value); -#define IV_DELIMITER_ENCODED @"|" //@"fA==" // "|" base64 encoded +#define IV_DELIMITER_ENCODED @"|" #define PBKDF2_INTERACTION_COUNT 1024 #define PBKDF2_KEY_LENGTH 256 //#define PBKDF2_SALT @"$4$YmBjm3hk$Qb74D5IUYwghUmzsMqeNFx5z0/8$" diff --git a/iOSClient/Security/NCEndToEndMetadata.swift b/iOSClient/Security/NCEndToEndMetadata.swift index 9377b4e1d..4ee936672 100644 --- a/iOSClient/Security/NCEndToEndMetadata.swift +++ b/iOSClient/Security/NCEndToEndMetadata.swift @@ -189,11 +189,9 @@ class NCEndToEndMetadata : NSObject { } do { - let encryptedFileAttributes = try jsonDecoder.decode(e2eMetadata.encryptedFileAttributes.self, from: encryptedFileAttributesJson.data(using: .utf8)!) - - let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account == %@ AND fileName == %@", account, fileNameIdentifier)) - if metadata != nil { + if let metadata = NCManageDatabase.sharedInstance.getMetadata(predicate: NSPredicate(format: "account == %@ AND fileName == %@", account, fileNameIdentifier)) { + let metadata = tableMetadata.init(value: metadata) let object = tableE2eEncryption() @@ -220,17 +218,15 @@ class NCEndToEndMetadata : NSObject { } // Update metadata on tableMetadata - metadata?.fileNameView = encryptedFileAttributes.filename + metadata.fileNameView = encryptedFileAttributes.filename - let results = NCCommunicationCommon.shared.getInternalContenType(fileName: encryptedFileAttributes.filename, contentType: metadata!.contentType, directory: metadata!.directory) + let results = NCCommunicationCommon.shared.getInternalContenType(fileName: encryptedFileAttributes.filename, contentType: metadata.contentType, directory: metadata.directory) - metadata?.contentType = results.contentType - metadata?.iconName = results.iconName - metadata?.typeFile = results.typeFile + metadata.contentType = results.contentType + metadata.iconName = results.iconName + metadata.typeFile = results.typeFile - DispatchQueue.main.async { - NCManageDatabase.sharedInstance.addMetadata(metadata!) - } + NCManageDatabase.sharedInstance.addMetadata(metadata) } } catch let error { diff --git a/iOSClient/Select/NCSelect.swift b/iOSClient/Select/NCSelect.swift index 7b6aa2128..33f03238e 100644 --- a/iOSClient/Select/NCSelect.swift +++ b/iOSClient/Select/NCSelect.swift @@ -680,10 +680,8 @@ extension NCSelect { } } - if let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: predicate!) { - - sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: false, sorted: datasourceSorted, ascending: datasourceAscending, activeAccount: appDelegate.activeAccount) - } + let metadatas = NCManageDatabase.sharedInstance.getMetadatas(predicate: predicate!) + sectionDatasource = CCSectionMetadata.creataDataSourseSectionMetadata(metadatas, listProgressMetadata: nil, groupByField: datasourceGroupBy, filterTypeFileImage: false, filterTypeFileVideo: false, filterLivePhoto: false, sorted: datasourceSorted, ascending: datasourceAscending, activeAccount: appDelegate.activeAccount) if withLoadFolder { loadFolder() @@ -711,7 +709,7 @@ extension NCSelect { networkInProgress = true collectionView.reloadData() - NCNetworking.shared.readFolder(serverUrl: serverUrl, account: appDelegate.activeAccount) { (account, metadataFolder, metadatas, errorCode, errorDescription) in + NCNetworking.shared.readFolder(serverUrl: serverUrl, account: appDelegate.activeAccount) { (account, metadataFolder, metadatas, metadatasChanged, errorCode, errorDescription) in self.networkInProgress = false self.loadDatasource(withLoadFolder: false) diff --git a/iOSClient/Settings/CCAdvanced.m b/iOSClient/Settings/CCAdvanced.m index 93587f754..fcecd5911 100755 --- a/iOSClient/Settings/CCAdvanced.m +++ b/iOSClient/Settings/CCAdvanced.m @@ -126,6 +126,27 @@ [section addFormRow:row]; } + // Section CAPABILITIES ------------------------------------------------- + /* + section = [XLFormSectionDescriptor formSection]; + [form addFormSection:section]; + section.footerTitle = NSLocalizedString(@"_view_capabilities_", nil); + + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"capabilities" rowType:XLFormRowDescriptorTypeButton title:NSLocalizedString(@"_capabilities_", nil)]; + row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundCell; + [row.cellConfig setObject:@(NSTextAlignmentLeft) forKey:@"textLabel.textAlignment"]; + [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"capabilities"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; + row.action.formBlock = ^(XLFormRowDescriptor * sender) { + + [self deselectFormRow:sender]; + + NCCapabilitiesViewController *capabilities = [[UIStoryboard storyboardWithName:@"NCCapabilitiesViewController" bundle:nil] instantiateInitialViewController]; + [self presentViewController:capabilities animated:YES completion:nil]; + }; + [section addFormRow:row]; + */ // Section CLEAR CACHE ------------------------------------------------- section = [XLFormSectionDescriptor formSection]; diff --git a/iOSClient/Settings/CCManageAccount.m b/iOSClient/Settings/CCManageAccount.m index c75b21bc7..9b4eb506e 100644 --- a/iOSClient/Settings/CCManageAccount.m +++ b/iOSClient/Settings/CCManageAccount.m @@ -43,47 +43,45 @@ XLFormSectionDescriptor *section; XLFormRowDescriptor *row; - NSArray *listAccount = [[NCManageDatabase sharedInstance] getAccounts]; - tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountActive]; + NSArray *accounts = [[NCManageDatabase sharedInstance] getAllAccount]; + tableAccount *accountActive = [[NCManageDatabase sharedInstance] getAccountActive]; // Section : ACCOUNTS ------------------------------------------- section = [XLFormSectionDescriptor formSectionWithTitle:NSLocalizedString(@"_accounts_", nil)]; [form addFormSection:section]; - form.rowNavigationOptions = XLFormRowNavigationOptionNone; - row = [XLFormRowDescriptor formRowDescriptorWithTag:@"pickerAccount" rowType:XLFormRowDescriptorTypePicker]; - row.height = 100; - if (listAccount.count > 0) { - row.selectorOptions = listAccount; - row.value = tableAccount.account; - } else { - row.selectorOptions = [[NSArray alloc] initWithObjects:@"", nil]; - } - - // Avatar - NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@-%@.png", [CCUtility getDirectoryUserData], [CCUtility getStringUser:appDelegate.activeUser activeUrl:appDelegate.activeUrl], appDelegate.activeUser]; - - UIImage *avatar = [UIImage imageWithContentsOfFile:fileNamePath]; - if (avatar) { - - avatar = [CCGraphics scaleImage:avatar toSize:CGSizeMake(40, 40) isAspectRation:YES]; - - CCAvatar *avatarImageView = [[CCAvatar alloc] initWithImage:avatar borderColor:[UIColor lightGrayColor] borderWidth:0.5]; + for (tableAccount *account in accounts) { - CGSize imageSize = avatarImageView.bounds.size; - UIGraphicsBeginImageContextWithOptions(imageSize, NO, UIScreen.mainScreen.scale); - CGContextRef context = UIGraphicsGetCurrentContext(); - [avatarImageView.layer renderInContext:context]; - avatar = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); + row = [XLFormRowDescriptor formRowDescriptorWithTag:account.account rowType:XLFormRowDescriptorTypeBooleanCheck title:account.account]; + // Avatar + NSString *fileNamePath = [NSString stringWithFormat:@"%@/%@-%@.png", [CCUtility getDirectoryUserData], [CCUtility getStringUser:account.user activeUrl:account.url], account.user]; + UIImage *avatar = [UIImage imageWithContentsOfFile:fileNamePath]; + if (avatar) { + + avatar = [CCGraphics scaleImage:avatar toSize:CGSizeMake(35, 35) isAspectRation:YES]; + + CCAvatar *avatarImageView = [[CCAvatar alloc] initWithImage:avatar borderColor:[UIColor lightGrayColor] borderWidth:0.5]; + + CGSize imageSize = avatarImageView.bounds.size; + UIGraphicsBeginImageContextWithOptions(imageSize, NO, UIScreen.mainScreen.scale); + CGContextRef context = UIGraphicsGetCurrentContext(); + [avatarImageView.layer renderInContext:context]; + avatar = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + } else { + avatar = [CCGraphics scaleImage:[UIImage imageNamed:@"avatarBN"] toSize:CGSizeMake(35, 35) isAspectRation:YES]; + } - } else { - avatar = [UIImage imageNamed:@"avatarBN"]; + row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundCell; + [row.cellConfig setObject:[UIFont systemFontOfSize:13.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:avatar forKey:@"imageView.image"]; + if (account.active) { + row.value = @"YES"; + } + [section addFormRow:row]; } - - [row.cellConfig setObject:avatar forKey:@"imageView.image"]; - [section addFormRow:row]; // Section : MANAGE ACCOUNT ------------------------------------------- @@ -114,7 +112,7 @@ [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"trash"] width:50 height:50 color:[UIColor redColor]] forKey:@"imageView.image"]; [row.cellConfig setObject:@(NSTextAlignmentLeft) forKey:@"textLabel.textAlignment"]; row.action.formSelector = @selector(deleteAccount:); - if (listAccount.count == 0) row.disabled = @YES; + if (accounts.count == 0) row.disabled = @YES; [section addFormRow:row]; } @@ -124,107 +122,107 @@ [form addFormSection:section]; // Full Name - if ([tableAccount.displayName length] > 0) { + if ([accountActive.displayName length] > 0) { row = [XLFormRowDescriptor formRowDescriptorWithTag:@"userfullname" rowType:XLFormRowDescriptorTypeInfo title:NSLocalizedString(@"_user_full_name_", nil)]; row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundCell; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"detailTextLabel.font"]; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"user"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; - row.value = tableAccount.displayName; + row.value = accountActive.displayName; [section addFormRow:row]; } // Address - if ([tableAccount.address length] > 0) { + if ([accountActive.address length] > 0) { row = [XLFormRowDescriptor formRowDescriptorWithTag:@"useraddress" rowType:XLFormRowDescriptorTypeInfo title:NSLocalizedString(@"_user_address_", nil)]; row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundCell; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"detailTextLabel.font"]; [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"address"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; - row.value = tableAccount.address; + row.value = accountActive.address; [section addFormRow:row]; } // City + zip - if ([tableAccount.city length] > 0) { + if ([accountActive.city length] > 0) { row = [XLFormRowDescriptor formRowDescriptorWithTag:@"usercity" rowType:XLFormRowDescriptorTypeInfo title:NSLocalizedString(@"_user_city_", nil)]; row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundCell; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"detailTextLabel.font"]; [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"city"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; - row.value = tableAccount.city; - if ([tableAccount.zip length] > 0) { - row.value = [NSString stringWithFormat:@"%@ %@", row.value, tableAccount.zip]; + row.value = accountActive.city; + if ([accountActive.zip length] > 0) { + row.value = [NSString stringWithFormat:@"%@ %@", row.value, accountActive.zip]; } [section addFormRow:row]; } // Country - if ([tableAccount.country length] > 0) { + if ([accountActive.country length] > 0) { row = [XLFormRowDescriptor formRowDescriptorWithTag:@"usercountry" rowType:XLFormRowDescriptorTypeInfo title:NSLocalizedString(@"_user_country_", nil)]; row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundCell; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"detailTextLabel.font"]; [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"country"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; - row.value = [[NSLocale systemLocale] displayNameForKey:NSLocaleCountryCode value:tableAccount.country]; + row.value = [[NSLocale systemLocale] displayNameForKey:NSLocaleCountryCode value:accountActive.country]; //NSArray *countryCodes = [NSLocale ISOCountryCodes]; [section addFormRow:row]; } // Phone - if ([tableAccount.phone length] > 0) { + if ([accountActive.phone length] > 0) { row = [XLFormRowDescriptor formRowDescriptorWithTag:@"userphone" rowType:XLFormRowDescriptorTypeInfo title:NSLocalizedString(@"_user_phone_", nil)]; row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundCell; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"detailTextLabel.font"]; [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"phone"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; - row.value = tableAccount.phone; + row.value = accountActive.phone; [section addFormRow:row]; } // Email - if ([tableAccount.email length] > 0) { + if ([accountActive.email length] > 0) { row = [XLFormRowDescriptor formRowDescriptorWithTag:@"useremail" rowType:XLFormRowDescriptorTypeInfo title:NSLocalizedString(@"_user_email_", nil)]; row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundCell; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"detailTextLabel.font"]; [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"email"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; - row.value = tableAccount.email; + row.value = accountActive.email; [section addFormRow:row]; } // Web - if ([tableAccount.webpage length] > 0) { + if ([accountActive.webpage length] > 0) { row = [XLFormRowDescriptor formRowDescriptorWithTag:@"userweb" rowType:XLFormRowDescriptorTypeInfo title:NSLocalizedString(@"_user_web_", nil)]; row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundCell; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"detailTextLabel.font"]; [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"web"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; - row.value = tableAccount.webpage; + row.value = accountActive.webpage; [section addFormRow:row]; } // Twitter - if ([tableAccount.twitter length] > 0) { + if ([accountActive.twitter length] > 0) { row = [XLFormRowDescriptor formRowDescriptorWithTag:@"usertwitter" rowType:XLFormRowDescriptorTypeInfo title:NSLocalizedString(@"_user_twitter_", nil)]; row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundCell; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"detailTextLabel.font"]; [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"twitter"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; - row.value = tableAccount.twitter; + row.value = accountActive.twitter; [section addFormRow:row]; } // Section : THIRT PART ------------------------------------------- - BOOL isHandwerkcloudEnabled = [[NCManageDatabase sharedInstance] getCapabilitiesServerBoolWithAccount:tableAccount.account elements:NCElementsJSON.shared.capabilitiesHWCEnabled exists:false]; + BOOL isHandwerkcloudEnabled = [[NCManageDatabase sharedInstance] getCapabilitiesServerBoolWithAccount:accountActive.account elements:NCElementsJSON.shared.capabilitiesHWCEnabled exists:false]; if (isHandwerkcloudEnabled) { section = [XLFormSectionDescriptor formSectionWithTitle:NSLocalizedString(@"_user_job_", nil)]; @@ -237,7 +235,7 @@ [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"detailTextLabel.font"]; [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"businesstype"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; - row.value = tableAccount.businessType; + row.value = accountActive.businessType; [section addFormRow:row]; // Business Size @@ -247,7 +245,7 @@ [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"detailTextLabel.font"]; [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"users"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; - row.value = tableAccount.businessSize; + row.value = accountActive.businessSize; [section addFormRow:row]; // Role @@ -257,9 +255,9 @@ [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"detailTextLabel.font"]; [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"role"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; - if ([tableAccount.role isEqualToString:@"owner"]) row.value = NSLocalizedString(@"_user_owner_", nil); - else if ([tableAccount.role isEqualToString:@"employee"]) row.value = NSLocalizedString(@"_user_employee_", nil); - else if ([tableAccount.role isEqualToString:@"contractor"]) row.value = NSLocalizedString(@"_user_contractor_", nil); + if ([accountActive.role isEqualToString:@"owner"]) row.value = NSLocalizedString(@"_user_owner_", nil); + else if ([accountActive.role isEqualToString:@"employee"]) row.value = NSLocalizedString(@"_user_employee_", nil); + else if ([accountActive.role isEqualToString:@"contractor"]) row.value = NSLocalizedString(@"_user_contractor_", nil); else row.value = @""; [section addFormRow:row]; @@ -270,10 +268,10 @@ [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"detailTextLabel.font"]; [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"company"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; - row.value = tableAccount.company; + row.value = accountActive.company; [section addFormRow:row]; - if (tableAccount.hcIsTrial) { + if (accountActive.hcIsTrial) { section = [XLFormSectionDescriptor formSectionWithTitle:NSLocalizedString(@"_trial_", nil)]; [form addFormSection:section]; @@ -285,7 +283,7 @@ [row.cellConfig setObject:[UIColor redColor] forKey:@"textLabel.textColor"]; [row.cellConfig setObject:[UIColor redColor] forKey:@"detailTextLabel.textColor"]; [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"timer"] width:50 height:50 color:[UIColor redColor]] forKey:@"imageView.image"]; - NSInteger numberOfDays = tableAccount.hcTrialRemainingSec / (24*3600); + NSInteger numberOfDays = accountActive.hcTrialRemainingSec / (24*3600); row.value = [@(numberOfDays) stringValue]; [section addFormRow:row]; } @@ -303,7 +301,7 @@ #if defined(HC) row.action.viewControllerClass = [HCEditProfile class]; #endif - if (listAccount.count == 0) row.disabled = @YES; + if (accounts.count == 0) row.disabled = @YES; [section addFormRow:row]; } @@ -311,7 +309,7 @@ self.form = form; // Open Login - if (listAccount.count == 0) { + if (accounts.count == 0) { [appDelegate openLoginView:self selector:k_intro_login openLoginWeb:false]; } } @@ -343,16 +341,13 @@ { [super formRowDescriptorValueHasChanged:rowDescriptor oldValue:oldValue newValue:newValue]; - if ([rowDescriptor.tag isEqualToString:@"pickerAccount"] && oldValue && newValue) { - - if (![newValue isEqualToString:oldValue] && ![newValue isEqualToString:@""] && ![newValue isEqualToString:appDelegate.activeAccount]) { - [self ChangeDefaultAccount:newValue]; - } - - if ([newValue isEqualToString:@""]) { - NSArray *listAccount = [[NCManageDatabase sharedInstance] getAccounts]; - if ([listAccount count] > 0) { - [self ChangeDefaultAccount:listAccount[0]]; + NSArray *accounts = [[NCManageDatabase sharedInstance] getAllAccount]; + tableAccount *accountActive = [[NCManageDatabase sharedInstance] getAccountActive]; + + for (tableAccount *account in accounts) { + if ([rowDescriptor.tag isEqualToString:account.account]) { + if (![account.account isEqualToString:accountActive.account]) { + [self ChangeDefaultAccount:account.account]; } } } @@ -381,10 +376,8 @@ [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_delete_", nil) style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) { - XLFormPickerCell *pickerAccount = (XLFormPickerCell *)[[self.form formRowWithTag:@"pickerAccount"] cellForFormController:self]; - - tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", pickerAccount.rowDescriptor.value]]; - NSString *account = tableAccount.account; + tableAccount *accountActive = [[NCManageDatabase sharedInstance] getAccountActive]; + NSString *account = accountActive.account; if (account) { [appDelegate deleteAccount:account wipe:false]; diff --git a/iOSClient/Settings/CCManageAutoUpload.m b/iOSClient/Settings/CCManageAutoUpload.m index 8389d8e80..d298076e0 100644 --- a/iOSClient/Settings/CCManageAutoUpload.m +++ b/iOSClient/Settings/CCManageAutoUpload.m @@ -487,7 +487,7 @@ if (serverUrl != nil) { if ([serverUrl isEqualToString:[CCUtility getHomeServerUrlActiveUrl:appDelegate.activeUrl]]) { - [[NCContentPresenter shared] messageNotification:@"_error_" description:@"_autoupload_error_select_folder_" delay:k_dismissAfterSecond type:messageTypeError errorCode:0]; + [[NCContentPresenter shared] messageNotification:@"_error_" description:@"_autoupload_error_select_folder_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError forced:true]; return; } diff --git a/iOSClient/Settings/CCSettings.m b/iOSClient/Settings/CCSettings.m index ec024275f..bf1a8b2bd 100644 --- a/iOSClient/Settings/CCSettings.m +++ b/iOSClient/Settings/CCSettings.m @@ -24,7 +24,6 @@ #import "CCSettings.h" #import "AppDelegate.h" #import "CCMain.h" -#import "CCSynchronize.h" #import "CCAdvanced.h" #import "CCManageAccount.h" #import "NCManageEndToEndEncryption.h" @@ -50,7 +49,7 @@ XLFormDescriptor *form = [XLFormDescriptor formDescriptor]; XLFormSectionDescriptor *section; XLFormRowDescriptor *row; - NSInteger serverVersionMajor = [[NCManageDatabase sharedInstance] getCapabilitiesServerIntWithAccount:appDelegate.activeAccount elements:NCElementsJSON.shared.capabilitiesVersionMajor]; + //NSInteger serverVersionMajor = [[NCManageDatabase sharedInstance] getCapabilitiesServerIntWithAccount:appDelegate.activeAccount elements:NCElementsJSON.shared.capabilitiesVersionMajor]; form.rowNavigationOptions = XLFormRowNavigationOptionNone; @@ -136,24 +135,21 @@ [section addFormRow:row]; } - // Section : E2EEncryption From Nextcloud 19 -------------------------------------------------------------- - - if (serverVersionMajor >= k_nextcloud_version_19_0) { - - section = [XLFormSectionDescriptor formSectionWithTitle:NSLocalizedString(@"_e2e_settings_title_", nil)]; - [form addFormSection:section]; - - // EndToEnd Encryption - NSString *title = [NSString stringWithFormat:@"%@ (%@)",NSLocalizedString(@"_e2e_settings_", nil), NSLocalizedString(@"_experimental_", nil)]; - row = [XLFormRowDescriptor formRowDescriptorWithTag:@"e2eEncryption" rowType:XLFormRowDescriptorTypeButton title:title]; - row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundCell; - [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; - [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; - [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"lock"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; - row.action.viewControllerClass = [NCManageEndToEndEncryption class]; + // Section : E2EEncryption -------------------------------------------------------------- - [section addFormRow:row]; - } + section = [XLFormSectionDescriptor formSectionWithTitle:NSLocalizedString(@"_e2e_settings_title_", nil)]; + [form addFormSection:section]; + + // EndToEnd Encryption + NSString *title = [NSString stringWithFormat:@"%@ (%@)",NSLocalizedString(@"_e2e_settings_", nil), NSLocalizedString(@"_experimental_", nil)]; + row = [XLFormRowDescriptor formRowDescriptorWithTag:@"e2eEncryption" rowType:XLFormRowDescriptorTypeButton title:title]; + row.cellConfigAtConfigure[@"backgroundColor"] = NCBrandColor.sharedInstance.backgroundCell; + [row.cellConfig setObject:[UIFont systemFontOfSize:15.0] forKey:@"textLabel.font"]; + [row.cellConfig setObject:NCBrandColor.sharedInstance.textView forKey:@"textLabel.textColor"]; + [row.cellConfig setObject:[CCGraphics changeThemingColorImage:[UIImage imageNamed:@"lock"] width:50 height:50 color:NCBrandColor.sharedInstance.icon] forKey:@"imageView.image"]; + row.action.viewControllerClass = [NCManageEndToEndEncryption class]; + + [section addFormRow:row]; // Section Advanced ------------------------------------------------- @@ -292,7 +288,7 @@ [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_ok_", nil) style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) { [CCUtility setFavoriteOffline:true]; - [appDelegate.activeFavorites listingFavorites]; + [[NCNetworking shared] listingFavoritescompletionWithCompletion:^(NSString *account, NSArray *metadatas, NSInteger errorCode, NSString *errorDescription) { }]; }]]; [alertController addAction: [UIAlertAction actionWithTitle:NSLocalizedString(@"_cancel_", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { diff --git a/iOSClient/Settings/NCCapabilitiesViewController.storyboard b/iOSClient/Settings/NCCapabilitiesViewController.storyboard new file mode 100644 index 000000000..6709ceadb --- /dev/null +++ b/iOSClient/Settings/NCCapabilitiesViewController.storyboard @@ -0,0 +1,227 @@ +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="vTK-Er-kbZ"> + <device id="retina6_1" orientation="portrait" appearance="light"/> + <dependencies> + <deployment identifier="iOS"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/> + <capability name="Safe area layout guides" minToolsVersion="9.0"/> + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> + </dependencies> + <scenes> + <!--Capabilities View Controller--> + <scene sceneID="UF0-FW-gHK"> + <objects> + <viewController id="7oH-vf-YqN" customClass="NCCapabilitiesViewController" customModule="Nextcloud" customModuleProvider="target" sceneMemberID="viewController"> + <view key="view" contentMode="scaleToFill" id="Aja-Mn-6Wc"> + <rect key="frame" x="0.0" y="0.0" width="414" height="896"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> + <subviews> + <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hTE-ys-qsF"> + <rect key="frame" x="0.0" y="88" width="414" height="774"/> + <subviews> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OO4-N7-9vp"> + <rect key="frame" x="0.0" y="160" width="414" height="43"/> + <subviews> + <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="RIO-6X-GG1"> + <rect key="frame" x="5" y="5" width="404" height="33"/> + <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> + <fontDescription key="fontDescription" type="system" pointSize="14"/> + <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/> + </textView> + </subviews> + <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> + <constraints> + <constraint firstItem="RIO-6X-GG1" firstAttribute="leading" secondItem="OO4-N7-9vp" secondAttribute="leading" constant="5" id="63w-yC-mGi"/> + <constraint firstAttribute="trailing" secondItem="RIO-6X-GG1" secondAttribute="trailing" constant="5" id="9cj-M6-K3f"/> + <constraint firstItem="RIO-6X-GG1" firstAttribute="top" secondItem="OO4-N7-9vp" secondAttribute="top" constant="5" id="ODH-TK-qMG"/> + <constraint firstAttribute="bottom" secondItem="RIO-6X-GG1" secondAttribute="bottom" constant="5" id="ajP-yK-idK"/> + </constraints> + </view> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Sms-Ez-fLO"> + <rect key="frame" x="5" y="5" width="404" height="150"/> + <subviews> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jdW-oZ-cH8" userLabel="FileSharing"> + <rect key="frame" x="0.0" y="0.0" width="404" height="50"/> + <subviews> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="share" translatesAutoresizingMaskIntoConstraints="NO" id="G9c-Nd-Ikl"> + <rect key="frame" x="0.0" y="10" width="30" height="30"/> + <constraints> + <constraint firstAttribute="width" constant="30" id="2jt-3Q-W9U"/> + <constraint firstAttribute="height" constant="30" id="qw0-LB-a0S"/> + </constraints> + </imageView> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="File sharing" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Olg-V3-URE"> + <rect key="frame" x="40" y="14.5" width="319" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="lGk-Lk-3Ya"> + <rect key="frame" x="369" y="12.5" width="25" height="25"/> + <constraints> + <constraint firstAttribute="height" constant="25" id="F1b-ve-eI1"/> + <constraint firstAttribute="width" constant="25" id="kg0-Ii-p7a"/> + </constraints> + </imageView> + </subviews> + <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> + <constraints> + <constraint firstAttribute="trailing" secondItem="lGk-Lk-3Ya" secondAttribute="trailing" constant="10" id="3q5-Rv-UgT"/> + <constraint firstAttribute="height" constant="50" id="486-j7-SKp"/> + <constraint firstItem="G9c-Nd-Ikl" firstAttribute="leading" secondItem="jdW-oZ-cH8" secondAttribute="leading" id="Bnm-Im-c7M"/> + <constraint firstItem="G9c-Nd-Ikl" firstAttribute="centerY" secondItem="jdW-oZ-cH8" secondAttribute="centerY" id="Jxk-cZ-ezx"/> + <constraint firstItem="lGk-Lk-3Ya" firstAttribute="leading" secondItem="Olg-V3-URE" secondAttribute="trailing" constant="10" id="KsG-sO-Ifp"/> + <constraint firstItem="lGk-Lk-3Ya" firstAttribute="centerY" secondItem="jdW-oZ-cH8" secondAttribute="centerY" id="LnL-I4-6bN"/> + <constraint firstItem="Olg-V3-URE" firstAttribute="centerY" secondItem="jdW-oZ-cH8" secondAttribute="centerY" id="RXs-zW-MT4"/> + <constraint firstItem="Olg-V3-URE" firstAttribute="leading" secondItem="G9c-Nd-Ikl" secondAttribute="trailing" constant="10" id="XZo-QH-gpr"/> + </constraints> + </view> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ZNB-jF-9zg" userLabel="direct editing"> + <rect key="frame" x="0.0" y="50" width="404" height="50"/> + <subviews> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="document" translatesAutoresizingMaskIntoConstraints="NO" id="iCB-2A-phO"> + <rect key="frame" x="0.0" y="10" width="30" height="30"/> + <constraints> + <constraint firstAttribute="width" constant="30" id="Ww6-2V-i4r"/> + <constraint firstAttribute="height" constant="30" id="kdP-OK-U2a"/> + </constraints> + </imageView> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Direct Editing" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FOv-Ld-QFB"> + <rect key="frame" x="40" y="14.5" width="319" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="LNE-l0-lef"> + <rect key="frame" x="369" y="12.5" width="25" height="25"/> + <constraints> + <constraint firstAttribute="height" constant="25" id="0uT-mh-bdL"/> + <constraint firstAttribute="width" constant="25" id="fIi-jh-MHl"/> + </constraints> + </imageView> + </subviews> + <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> + <constraints> + <constraint firstAttribute="height" constant="50" id="4UX-0n-U4U"/> + <constraint firstItem="LNE-l0-lef" firstAttribute="leading" secondItem="FOv-Ld-QFB" secondAttribute="trailing" constant="10" id="VYE-Ty-lSC"/> + <constraint firstItem="LNE-l0-lef" firstAttribute="centerY" secondItem="ZNB-jF-9zg" secondAttribute="centerY" id="YUU-Eq-LA1"/> + <constraint firstItem="iCB-2A-phO" firstAttribute="leading" secondItem="ZNB-jF-9zg" secondAttribute="leading" id="cF1-co-eQB"/> + <constraint firstItem="iCB-2A-phO" firstAttribute="centerY" secondItem="ZNB-jF-9zg" secondAttribute="centerY" id="gSQ-hN-iBx"/> + <constraint firstItem="FOv-Ld-QFB" firstAttribute="leading" secondItem="iCB-2A-phO" secondAttribute="trailing" constant="10" id="kiE-oZ-ky6"/> + <constraint firstAttribute="trailing" secondItem="LNE-l0-lef" secondAttribute="trailing" constant="10" id="mbK-XX-6bb"/> + <constraint firstItem="FOv-Ld-QFB" firstAttribute="centerY" secondItem="ZNB-jF-9zg" secondAttribute="centerY" id="vHG-Fk-kEj"/> + </constraints> + </view> + <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="mSC-JU-xuk" userLabel="external Site"> + <rect key="frame" x="0.0" y="100" width="404" height="50"/> + <subviews> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="country" translatesAutoresizingMaskIntoConstraints="NO" id="JWO-C0-32L"> + <rect key="frame" x="0.0" y="10" width="30" height="30"/> + <constraints> + <constraint firstAttribute="height" constant="30" id="cuQ-hf-WGC"/> + <constraint firstAttribute="width" constant="30" id="hun-lk-Hyf"/> + </constraints> + </imageView> + <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="External site" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="g2c-tp-kiW"> + <rect key="frame" x="40" y="14.5" width="319" height="21"/> + <fontDescription key="fontDescription" type="system" pointSize="17"/> + <nil key="textColor"/> + <nil key="highlightedColor"/> + </label> + <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="GRj-nZ-KYG"> + <rect key="frame" x="369" y="12.5" width="25" height="25"/> + <constraints> + <constraint firstAttribute="height" constant="25" id="7MW-hB-PpI"/> + <constraint firstAttribute="width" constant="25" id="WvT-WM-YU5"/> + </constraints> + </imageView> + </subviews> + <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> + <constraints> + <constraint firstItem="JWO-C0-32L" firstAttribute="centerY" secondItem="mSC-JU-xuk" secondAttribute="centerY" id="FLD-bX-ETy"/> + <constraint firstItem="GRj-nZ-KYG" firstAttribute="leading" secondItem="g2c-tp-kiW" secondAttribute="trailing" constant="10" id="GWm-I1-YH0"/> + <constraint firstItem="GRj-nZ-KYG" firstAttribute="centerY" secondItem="mSC-JU-xuk" secondAttribute="centerY" id="Sae-AX-SxD"/> + <constraint firstItem="g2c-tp-kiW" firstAttribute="leading" secondItem="JWO-C0-32L" secondAttribute="trailing" constant="10" id="fWw-rx-nFV"/> + <constraint firstAttribute="trailing" secondItem="GRj-nZ-KYG" secondAttribute="trailing" constant="10" id="k9Z-1W-giE"/> + <constraint firstAttribute="height" constant="50" id="pLI-AP-DaV"/> + <constraint firstItem="JWO-C0-32L" firstAttribute="leading" secondItem="mSC-JU-xuk" secondAttribute="leading" id="pyK-ZG-7fZ"/> + <constraint firstItem="g2c-tp-kiW" firstAttribute="centerY" secondItem="mSC-JU-xuk" secondAttribute="centerY" id="rtm-fS-6ec"/> + </constraints> + </view> + </subviews> + <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> + <constraints> + <constraint firstItem="mSC-JU-xuk" firstAttribute="top" secondItem="ZNB-jF-9zg" secondAttribute="bottom" id="3ao-So-g0n"/> + <constraint firstAttribute="height" constant="150" id="6nU-Cb-MzH"/> + <constraint firstItem="mSC-JU-xuk" firstAttribute="leading" secondItem="Sms-Ez-fLO" secondAttribute="leading" id="9Nq-du-3ah"/> + <constraint firstItem="ZNB-jF-9zg" firstAttribute="leading" secondItem="Sms-Ez-fLO" secondAttribute="leading" id="GdE-lt-vZC"/> + <constraint firstItem="ZNB-jF-9zg" firstAttribute="top" secondItem="jdW-oZ-cH8" secondAttribute="bottom" id="KcV-Ki-sGP"/> + <constraint firstItem="jdW-oZ-cH8" firstAttribute="top" secondItem="Sms-Ez-fLO" secondAttribute="top" id="UBW-Mx-NTs"/> + <constraint firstItem="jdW-oZ-cH8" firstAttribute="leading" secondItem="Sms-Ez-fLO" secondAttribute="leading" id="eNi-cO-UFd"/> + <constraint firstAttribute="trailing" secondItem="jdW-oZ-cH8" secondAttribute="trailing" id="k81-ap-Nwy"/> + <constraint firstAttribute="trailing" secondItem="mSC-JU-xuk" secondAttribute="trailing" id="pBU-xQ-0qV"/> + <constraint firstAttribute="trailing" secondItem="ZNB-jF-9zg" secondAttribute="trailing" id="v5H-SV-MvM"/> + </constraints> + </view> + </subviews> + <constraints> + <constraint firstItem="OO4-N7-9vp" firstAttribute="top" secondItem="hTE-ys-qsF" secondAttribute="top" constant="160" id="A9O-TK-Vz6"/> + <constraint firstAttribute="bottom" secondItem="OO4-N7-9vp" secondAttribute="bottom" id="MpX-OZ-MDh"/> + <constraint firstItem="OO4-N7-9vp" firstAttribute="width" secondItem="hTE-ys-qsF" secondAttribute="width" id="PWW-C3-Qcw"/> + <constraint firstItem="OO4-N7-9vp" firstAttribute="leading" secondItem="hTE-ys-qsF" secondAttribute="leading" id="Q4I-CY-qdY"/> + <constraint firstAttribute="trailing" secondItem="OO4-N7-9vp" secondAttribute="trailing" id="cmw-yc-oJP"/> + <constraint firstAttribute="trailing" secondItem="Sms-Ez-fLO" secondAttribute="trailing" constant="5" id="coa-ak-YgW"/> + <constraint firstItem="Sms-Ez-fLO" firstAttribute="leading" secondItem="hTE-ys-qsF" secondAttribute="leading" constant="5" id="rIR-0f-qtc"/> + <constraint firstItem="Sms-Ez-fLO" firstAttribute="top" secondItem="hTE-ys-qsF" secondAttribute="top" constant="5" id="tsB-Td-qaK"/> + </constraints> + </scrollView> + </subviews> + <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> + <constraints> + <constraint firstItem="uBS-U0-Obf" firstAttribute="trailing" secondItem="hTE-ys-qsF" secondAttribute="trailing" id="CvM-Hx-Hy6"/> + <constraint firstItem="hTE-ys-qsF" firstAttribute="top" secondItem="uBS-U0-Obf" secondAttribute="top" id="Lar-wg-a7V"/> + <constraint firstItem="hTE-ys-qsF" firstAttribute="leading" secondItem="uBS-U0-Obf" secondAttribute="leading" id="Mye-Fv-DDH"/> + <constraint firstItem="uBS-U0-Obf" firstAttribute="bottom" secondItem="hTE-ys-qsF" secondAttribute="bottom" id="aJj-P3-LeK"/> + </constraints> + <viewLayoutGuide key="safeArea" id="uBS-U0-Obf"/> + </view> + <navigationItem key="navigationItem" id="fnR-ht-Muv"/> + <connections> + <outlet property="imageDirectEditing" destination="iCB-2A-phO" id="J35-Op-36Q"/> + <outlet property="imageExternalSite" destination="JWO-C0-32L" id="JKi-n1-5IQ"/> + <outlet property="imageFileSharing" destination="G9c-Nd-Ikl" id="Wha-2g-8o0"/> + <outlet property="imageStatusDirectEditing" destination="LNE-l0-lef" id="YrK-IF-D73"/> + <outlet property="imageStatusExternalSite" destination="GRj-nZ-KYG" id="7hn-jn-LO4"/> + <outlet property="imageStatusFileSharing" destination="lGk-Lk-3Ya" id="i7x-7x-TtE"/> + <outlet property="textView" destination="RIO-6X-GG1" id="lPs-Ev-hQf"/> + </connections> + </viewController> + <placeholder placeholderIdentifier="IBFirstResponder" id="0OV-l8-tBJ" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="910.14492753623199" y="133.25892857142856"/> + </scene> + <!--Navigation Controller--> + <scene sceneID="YbF-Ed-KAp"> + <objects> + <navigationController automaticallyAdjustsScrollViewInsets="NO" id="vTK-Er-kbZ" sceneMemberID="viewController"> + <toolbarItems/> + <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="f2L-7c-zw8"> + <rect key="frame" x="0.0" y="44" width="414" height="44"/> + <autoresizingMask key="autoresizingMask"/> + </navigationBar> + <nil name="viewControllers"/> + <connections> + <segue destination="7oH-vf-YqN" kind="relationship" relationship="rootViewController" id="ZBj-sH-5gE"/> + </connections> + </navigationController> + <placeholder placeholderIdentifier="IBFirstResponder" id="RAt-Xm-BSR" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/> + </objects> + <point key="canvasLocation" x="0.0" y="133.25892857142856"/> + </scene> + </scenes> + <resources> + <image name="country" width="300" height="300"/> + <image name="document" width="300" height="300"/> + <image name="share" width="512" height="512"/> + </resources> +</document> diff --git a/iOSClient/Settings/NCCapabilitiesViewController.swift b/iOSClient/Settings/NCCapabilitiesViewController.swift new file mode 100644 index 000000000..4ecc15efd --- /dev/null +++ b/iOSClient/Settings/NCCapabilitiesViewController.swift @@ -0,0 +1,97 @@ +// +// NCCapabilitiesViewController.swift +// Nextcloud +// +// Created by Marino Faggiana on 28/07/2020. +// Copyright © 2020 Marino Faggiana. All rights reserved. +// +// Author Marino Faggiana <marino.faggiana@nextcloud.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +import UIKit + +class NCCapabilitiesViewController: UIViewController { + + @IBOutlet weak var textView: UITextView! + + @IBOutlet weak var imageFileSharing: UIImageView! + @IBOutlet weak var imageStatusFileSharing: UIImageView! + + @IBOutlet weak var imageDirectEditing: UIImageView! + @IBOutlet weak var imageStatusDirectEditing: UIImageView! + + @IBOutlet weak var imageExternalSite: UIImageView! + @IBOutlet weak var imageStatusExternalSite: UIImageView! + + private var account: String = "" + private var imageEnable: UIImage? + private var imageDisable: UIImage? + + override func viewDidLoad() { + super.viewDidLoad() + + self.title = NSLocalizedString("_capabilities_", comment: "") + + let closeButton : UIBarButtonItem = UIBarButtonItem(title: NSLocalizedString("_done_", comment: ""), style: UIBarButtonItem.Style.plain, target: self, action: #selector(close)) + self.navigationItem.leftBarButtonItem = closeButton + + imageEnable = CCGraphics.changeThemingColorImage(UIImage.init(named: "circle"), width: 50, height: 50, color: .green) + imageDisable = CCGraphics.changeThemingColorImage(UIImage.init(named: "circle"), width: 50, height: 50, color: .red) + imageFileSharing.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "share"), width: 100, height: 100, color: .gray) + imageDirectEditing.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "document"), width: 100, height: 100, color: .gray) + imageExternalSite.image = CCGraphics.changeThemingColorImage(UIImage.init(named: "country"), width: 100, height: 100, color: .gray) + + guard let account = NCManageDatabase.sharedInstance.getAccountActive() else { return } + self.account = account.account + + if let jsonText = NCManageDatabase.sharedInstance.getCapabilities(account: account.account) { + textView.text = jsonText + readCapabilities() + } else { + NCContentPresenter.shared.messageNotification("_error_", description: "_no_capabilities_found_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorInternalError), forced: true) + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { + self.dismiss(animated: true, completion: nil) + } + } + } + + @objc func close() { + + self.dismiss(animated: true, completion: nil) + } + + func readCapabilities() { + + if NCManageDatabase.sharedInstance.getCapabilitiesServerBool(account: account, elements: NCElementsJSON.shared.capabilitiesFileSharingApiEnabled, exists: false) { + imageStatusFileSharing.image = imageEnable + } else { + imageStatusFileSharing.image = imageDisable + } + + if NCManageDatabase.sharedInstance.getDirectEditingCreators(account: account) != nil { + imageStatusDirectEditing.image = imageEnable + } else { + imageStatusDirectEditing.image = imageDisable + } + + if NCManageDatabase.sharedInstance.getCapabilitiesServerBool(account: account, elements: NCElementsJSON.shared.capabilitiesExternalSitesExists, exists: false) { + imageStatusExternalSite.image = imageEnable + } else { + imageStatusExternalSite.image = imageDisable + } + } +} diff --git a/iOSClient/Settings/NCManageAutoUploadFileName.swift b/iOSClient/Settings/NCManageAutoUploadFileName.swift index 44c3af140..4c51b54cf 100644 --- a/iOSClient/Settings/NCManageAutoUploadFileName.swift +++ b/iOSClient/Settings/NCManageAutoUploadFileName.swift @@ -170,7 +170,7 @@ class NCManageAutoUploadFileName: XLFormViewController { self.reloadFormRow(formRow) - NCContentPresenter.shared.messageNotification("_info_", description: "_forbidden_characters_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: 0) + NCContentPresenter.shared.messageNotification("_info_", description: "_forbidden_characters_", delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.info, errorCode: Int(k_CCErrorCharactersForbidden), forced: true) } } diff --git a/iOSClient/Settings/NCManageEndToEndEncryption.m b/iOSClient/Settings/NCManageEndToEndEncryption.m index 28a31eaa8..71fa386b0 100644 --- a/iOSClient/Settings/NCManageEndToEndEncryption.m +++ b/iOSClient/Settings/NCManageEndToEndEncryption.m @@ -44,14 +44,20 @@ XLFormRowDescriptor *row; BOOL isE2EEEnabled = [[NCManageDatabase sharedInstance] getCapabilitiesServerBoolWithAccount:appDelegate.activeAccount elements:NCElementsJSON.shared.capabilitiesE2EEEnabled exists:false]; - // DISABLE E2EE - isE2EEEnabled = NO; - // DISABLE E2EE - if (isE2EEEnabled == NO) { + NSString *versionE2EE = [[NCManageDatabase sharedInstance] getCapabilitiesServerStringWithAccount:appDelegate.activeAccount elements:NCElementsJSON.shared.capabilitiesE2EEApiVersion]; + + if (![versionE2EE isEqual:k_E2EE_API] && isE2EEEnabled) { + [[NCContentPresenter shared] messageNotification:@"_error_e2ee_" description:@"_err_e2ee_app_version_" delay:k_dismissAfterSecond type:messageTypeError errorCode:k_CCErrorInternalError forced:true]; + } + + if (isE2EEEnabled == NO || ![versionE2EE isEqual:k_E2EE_API]) { // Section SERVICE NOT AVAILABLE ------------------------------------------------- section = [XLFormSectionDescriptor formSection]; + if (isE2EEEnabled) { + section.footerTitle = [NSString stringWithFormat:@"End-to-End Encryption %@", versionE2EE]; + } [form addFormSection:section]; row = [XLFormRowDescriptor formRowDescriptorWithTag:@"serviceActivated" rowType:XLFormRowDescriptorTypeInfo title:NSLocalizedString(@"_e2e_settings_not_available_", nil)]; @@ -73,6 +79,7 @@ // Section SERVICE ACTIVATED ------------------------------------------------- section = [XLFormSectionDescriptor formSection]; + section.footerTitle = [NSString stringWithFormat:@"End-to-End Encryption %@", versionE2EE]; [form addFormSection:section]; row = [XLFormRowDescriptor formRowDescriptorWithTag:@"serviceActivated" rowType:XLFormRowDescriptorTypeInfo title:NSLocalizedString(@"_e2e_settings_activated_", nil)]; @@ -363,9 +370,9 @@ [[NCCommunication shared] deleteE2EEPublicKeyWithCustomUserAgent:nil addCustomHeaders:nil completionHandler:^(NSString *account, NSInteger errorCode, NSString *errorDescription) { if (errorCode == 0 && [account isEqualToString:appDelegate.activeAccount]) { - [[NCContentPresenter shared] messageNotification:@"E2E delete publicKey" description:@"Success" delay:k_dismissAfterSecond type:messageTypeSuccess errorCode:0]; + [[NCContentPresenter shared] messageNotification:@"E2E delete publicKey" description:@"Success" delay:k_dismissAfterSecond type:messageTypeSuccess errorCode:k_CCErrorInternalError forced:true]; } else { - [[NCContentPresenter shared] messageNotification:@"E2E delete publicKey" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode]; + [[NCContentPresenter shared] messageNotification:@"E2E delete publicKey" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:true]; } }]; } @@ -376,9 +383,9 @@ [[NCCommunication shared] deleteE2EEPrivateKeyWithCustomUserAgent:nil addCustomHeaders:nil completionHandler:^(NSString *account, NSInteger errorCode, NSString *errorDescription) { if (errorCode == 0 && [account isEqualToString:appDelegate.activeAccount]) { - [[NCContentPresenter shared] messageNotification:@"E2E delete privateKey" description:@"Success" delay:k_dismissAfterSecond type:messageTypeSuccess errorCode:0]; + [[NCContentPresenter shared] messageNotification:@"E2E delete privateKey" description:@"Success" delay:k_dismissAfterSecond type:messageTypeSuccess errorCode:k_CCErrorInternalError forced:true]; } else { - [[NCContentPresenter shared] messageNotification:@"E2E delete privateKey" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode]; + [[NCContentPresenter shared] messageNotification:@"E2E delete privateKey" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:true]; } }]; } diff --git a/iOSClient/Share/NCShareNetworking.swift b/iOSClient/Share/NCShareNetworking.swift index 7711b329f..db4051179 100644 --- a/iOSClient/Share/NCShareNetworking.swift +++ b/iOSClient/Share/NCShareNetworking.swift @@ -52,7 +52,7 @@ class NCShareNetworking: NSObject { NCManageDatabase.sharedInstance.addShare(account: self.metadata.account, activeUrl: self.activeUrl, shares: shares!) self.appDelegate.shares = NCManageDatabase.sharedInstance.getTableShares(account: self.metadata.account) } else { - NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0) + NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true) } self.delegate?.readShareCompleted() } @@ -67,7 +67,7 @@ class NCShareNetworking: NSObject { NCManageDatabase.sharedInstance.addShare(account: self.metadata.account, activeUrl: self.activeUrl, shares: [share!]) self.appDelegate.shares = NCManageDatabase.sharedInstance.getTableShares(account: self.metadata.account) } else if errorCode != 0 { - NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0) + NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true) } self.delegate?.shareCompleted() } @@ -84,7 +84,7 @@ class NCShareNetworking: NSObject { NCManageDatabase.sharedInstance.addShare(account: self.metadata.account, activeUrl: self.activeUrl, shares: [share!]) self.appDelegate.shares = NCManageDatabase.sharedInstance.getTableShares(account: self.metadata.account) } else { - NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0) + NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true) } self.delegate?.shareCompleted() } @@ -98,7 +98,7 @@ class NCShareNetworking: NSObject { NCManageDatabase.sharedInstance.deleteTableShare(account: account, idShare: idShare) self.delegate?.unShareCompleted() } else { - NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0) + NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true) } } } @@ -112,7 +112,7 @@ class NCShareNetworking: NSObject { self.appDelegate.shares = NCManageDatabase.sharedInstance.getTableShares(account: self.metadata.account) self.delegate?.readShareCompleted() } else { - NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0) + NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true) self.delegate?.updateShareWithError(idShare: idShare) } } @@ -125,7 +125,7 @@ class NCShareNetworking: NSObject { if errorCode == 0 { self.delegate?.getSharees(sharees: sharees) } else { - NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: 0) + NCContentPresenter.shared.messageNotification("_share_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: Int(k_CCErrorInternalError), forced: true) self.delegate?.getSharees(sharees: nil) } } diff --git a/iOSClient/Share/NCSharePaging.swift b/iOSClient/Share/NCSharePaging.swift index 24e738360..d1074ad2c 100644 --- a/iOSClient/Share/NCSharePaging.swift +++ b/iOSClient/Share/NCSharePaging.swift @@ -68,7 +68,7 @@ class NCSharePaging: UIViewController { pagingViewController.dataSource = self pagingViewController.delegate = self pagingViewController.select(index: indexPage) - let pagingIndexItem = self.pagingViewController(pagingViewController, pagingItemForIndex: indexPage) as PagingIndexItem + let pagingIndexItem = self.pagingViewController(pagingViewController, pagingItemAt: indexPage) as! PagingIndexItem self.title = pagingIndexItem.title changeTheming() @@ -110,7 +110,7 @@ class NCSharePaging: UIViewController { extension NCSharePaging: PagingViewControllerDelegate { - func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, willScrollToItem pagingItem: T, startingViewController: UIViewController, destinationViewController: UIViewController) where T : PagingItem, T : Comparable, T : Hashable { + func pagingViewController(_ pagingViewController: PagingViewController, willScrollToItem pagingItem: PagingItem, startingViewController: UIViewController, destinationViewController: UIViewController) { guard let item = pagingItem as? PagingIndexItem else { return } self.title = item.title @@ -121,8 +121,8 @@ extension NCSharePaging: PagingViewControllerDelegate { extension NCSharePaging: PagingViewControllerDataSource { - func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, viewControllerForIndex index: Int) -> UIViewController { - + func pagingViewController(_: PagingViewController, viewControllerAt index: Int) -> UIViewController { + let height = pagingViewController.options.menuHeight + NCSharePagingView.HeaderHeight let topSafeArea = UIApplication.shared.keyWindow?.safeAreaInsets.top ?? 0 @@ -149,27 +149,28 @@ extension NCSharePaging: PagingViewControllerDataSource { } } - func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, pagingItemForIndex index: Int) -> T { + func pagingViewController(_: PagingViewController, pagingItemAt index: Int) -> PagingItem { + switch index { case 0: - return PagingIndexItem(index: index, title: NSLocalizedString("_activity_", comment: "")) as! T + return PagingIndexItem(index: index, title: NSLocalizedString("_activity_", comment: "")) case 1: - return PagingIndexItem(index: index, title: NSLocalizedString("_comments_", comment: "")) as! T + return PagingIndexItem(index: index, title: NSLocalizedString("_comments_", comment: "")) case 2: - return PagingIndexItem(index: index, title: NSLocalizedString("_sharing_", comment: "")) as! T + return PagingIndexItem(index: index, title: NSLocalizedString("_sharing_", comment: "")) default: - return PagingIndexItem(index: index, title: "") as! T + return PagingIndexItem(index: index, title: "") } } - - func numberOfViewControllers<T>(in: PagingViewController<T>) -> Int{ + + func numberOfViewControllers(in pagingViewController: PagingViewController) -> Int { return 3 } } // MARK: - Header -class NCShareHeaderViewController: PagingViewController<PagingIndexItem> { +class NCShareHeaderViewController: PagingViewController { public var image: UIImage? public var metadata: tableMetadata? diff --git a/iOSClient/Shares/NCShares.m b/iOSClient/Shares/NCShares.m index 275900f6d..609b4512c 100644 --- a/iOSClient/Shares/NCShares.m +++ b/iOSClient/Shares/NCShares.m @@ -170,7 +170,7 @@ [self reloadDatasource]; } else if (errorCode != 0) { - [[NCContentPresenter shared] messageNotification:@"_share_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode]; + [[NCContentPresenter shared] messageNotification:@"_share_" description:errorDescription delay:k_dismissAfterSecond type:messageTypeError errorCode:errorCode forced:true]; } else { NSLog(@"[LOG] It has been changed user during networking process, error."); } diff --git a/iOSClient/Supporting Files/af.lproj/Localizable.strings b/iOSClient/Supporting Files/af.lproj/Localizable.strings Binary files differindex 32d14ef01..3b1b1fa90 100644 --- a/iOSClient/Supporting Files/af.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/af.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ar.lproj/Localizable.strings b/iOSClient/Supporting Files/ar.lproj/Localizable.strings Binary files differindex 921a83a6c..263e61731 100644 --- a/iOSClient/Supporting Files/ar.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ar.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ast.lproj/Localizable.strings b/iOSClient/Supporting Files/ast.lproj/Localizable.strings Binary files differindex ab4836fe8..9526638af 100644 --- a/iOSClient/Supporting Files/ast.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ast.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/az.lproj/Localizable.strings b/iOSClient/Supporting Files/az.lproj/Localizable.strings Binary files differindex e6484dc6e..474039b9b 100644 --- a/iOSClient/Supporting Files/az.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/az.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/be.lproj/Localizable.strings b/iOSClient/Supporting Files/be.lproj/Localizable.strings Binary files differindex 77aeca0ef..fa929451a 100644 --- a/iOSClient/Supporting Files/be.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/be.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/bg_BG.lproj/Localizable.strings b/iOSClient/Supporting Files/bg_BG.lproj/Localizable.strings Binary files differindex 51b712236..0a84997ef 100644 --- a/iOSClient/Supporting Files/bg_BG.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/bg_BG.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/bn_BD.lproj/Localizable.strings b/iOSClient/Supporting Files/bn_BD.lproj/Localizable.strings Binary files differindex 2968a49df..2c410bcf6 100644 --- a/iOSClient/Supporting Files/bn_BD.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/bn_BD.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/bs.lproj/Localizable.strings b/iOSClient/Supporting Files/bs.lproj/Localizable.strings Binary files differindex ff32af95a..996ca15fb 100644 --- a/iOSClient/Supporting Files/bs.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/bs.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ca.lproj/Localizable.strings b/iOSClient/Supporting Files/ca.lproj/Localizable.strings Binary files differindex 6e8ee4251..4bea72228 100644 --- a/iOSClient/Supporting Files/ca.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ca.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings b/iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings Binary files differindex 6db6a6651..ab2781b64 100644 --- a/iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/cs-CZ.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/cy_GB.lproj/Localizable.strings b/iOSClient/Supporting Files/cy_GB.lproj/Localizable.strings Binary files differindex c476b85bf..5ce2fe764 100644 --- a/iOSClient/Supporting Files/cy_GB.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/cy_GB.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/da.lproj/Localizable.strings b/iOSClient/Supporting Files/da.lproj/Localizable.strings Binary files differindex 7a25c58e2..426c76ffe 100644 --- a/iOSClient/Supporting Files/da.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/da.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/de.lproj/Localizable.strings b/iOSClient/Supporting Files/de.lproj/Localizable.strings Binary files differindex 4dfbae451..aac03cb22 100644 --- a/iOSClient/Supporting Files/de.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/de.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/el.lproj/Localizable.strings b/iOSClient/Supporting Files/el.lproj/Localizable.strings Binary files differindex 47563d0e5..6300f88f8 100644 --- a/iOSClient/Supporting Files/el.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/el.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/en-GB.lproj/Localizable.strings b/iOSClient/Supporting Files/en-GB.lproj/Localizable.strings Binary files differindex 641492ee6..ea4028e67 100644 --- a/iOSClient/Supporting Files/en-GB.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/en-GB.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/en.lproj/Localizable.strings b/iOSClient/Supporting Files/en.lproj/Localizable.strings index 9cde5fa89..c96384175 100755 --- a/iOSClient/Supporting Files/en.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/en.lproj/Localizable.strings @@ -101,6 +101,7 @@ "_denied_album_" = "This app does not have access to \"Photos\", you can enable access in Privacy Settings"; "_denied_camera_" = "This app does not have access to \"Camera\", you can enable access in Privacy Settings"; "_start_" = "Start"; +"_force_start_" = "Force the start"; "_purchase_" = "Purchase"; "_account_not_available_" = "The account %@ of %@ does not exist, please add it to be able to read the file %@"; "_error_parameter_schema_" = "Wrong parameters, impossible to continue"; @@ -289,6 +290,9 @@ "_crashservice_alert_" = "This option requires a restart of the app to take effect"; "_upload_mov_livephoto_" = "Live Photo"; "_upload_mov_livephoto_footer_" = "\"Live Photo\" will save, when possible, the photo selected in \"Live Photo\" format"; +"_view_capabilities_" = "View the capabilities"; +"_capabilities_" = "Capabilities"; +"_no_capabilities_found_" = "Capabilities not found"; // Login @@ -674,6 +678,7 @@ "_e2e_error_delete_mark_folder_" = "Decrypt marked folder"; "_e2e_error_mark_folder_" = "Encrypt folder"; "_e2e_error_directory_not_empty_" = "The directory is not empty"; +"_e2e_error_not_move_" = "It is not possible move files to encrypted directory"; // Scan Document @@ -789,6 +794,9 @@ "_error_decode_xml_" = "Invalid response, error decode XML"; "_internal_generic_error_" = "internal error"; "_editor_unknown_" = "Failed to open file: Editor is unknown"; +"_err_asset_not_found_locally_" = "Error photo/video not found locally, removed from upload"; +"_err_asset_not_found_" = "Error photo/video not found, removed from upload"; +"_err_e2ee_app_version_" = "Error, the version of app End-to-End Encryption is not compatible, please update your server"; // QRCode diff --git a/iOSClient/Supporting Files/eo.lproj/Localizable.strings b/iOSClient/Supporting Files/eo.lproj/Localizable.strings Binary files differindex 61873b175..0d75ab5df 100644 --- a/iOSClient/Supporting Files/eo.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/eo.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-419.lproj/Localizable.strings b/iOSClient/Supporting Files/es-419.lproj/Localizable.strings Binary files differindex 5264699f9..f767e4fb8 100644 --- a/iOSClient/Supporting Files/es-419.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-419.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-AR.lproj/Localizable.strings b/iOSClient/Supporting Files/es-AR.lproj/Localizable.strings Binary files differindex 2e151555b..0bae67e06 100644 --- a/iOSClient/Supporting Files/es-AR.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-AR.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-CL.lproj/Localizable.strings b/iOSClient/Supporting Files/es-CL.lproj/Localizable.strings Binary files differindex 90d39e042..82e5a4fe4 100644 --- a/iOSClient/Supporting Files/es-CL.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-CL.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-CO.lproj/Localizable.strings b/iOSClient/Supporting Files/es-CO.lproj/Localizable.strings Binary files differindex 90d39e042..82e5a4fe4 100644 --- a/iOSClient/Supporting Files/es-CO.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-CO.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-CR.lproj/Localizable.strings b/iOSClient/Supporting Files/es-CR.lproj/Localizable.strings Binary files differindex 90d39e042..82e5a4fe4 100644 --- a/iOSClient/Supporting Files/es-CR.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-CR.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-DO.lproj/Localizable.strings b/iOSClient/Supporting Files/es-DO.lproj/Localizable.strings Binary files differindex 90d39e042..82e5a4fe4 100644 --- a/iOSClient/Supporting Files/es-DO.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-DO.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-EC.lproj/Localizable.strings b/iOSClient/Supporting Files/es-EC.lproj/Localizable.strings Binary files differindex 90d39e042..82e5a4fe4 100644 --- a/iOSClient/Supporting Files/es-EC.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-EC.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-GT.lproj/Localizable.strings b/iOSClient/Supporting Files/es-GT.lproj/Localizable.strings Binary files differindex 90d39e042..82e5a4fe4 100644 --- a/iOSClient/Supporting Files/es-GT.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-GT.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-HN.lproj/Localizable.strings b/iOSClient/Supporting Files/es-HN.lproj/Localizable.strings Binary files differindex 9a165ce4d..38f56fcd1 100644 --- a/iOSClient/Supporting Files/es-HN.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-HN.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-MX.lproj/Localizable.strings b/iOSClient/Supporting Files/es-MX.lproj/Localizable.strings Binary files differindex f8d193d91..39d1c746a 100644 --- a/iOSClient/Supporting Files/es-MX.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-MX.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-NI.lproj/Localizable.strings b/iOSClient/Supporting Files/es-NI.lproj/Localizable.strings Binary files differindex 9a165ce4d..38f56fcd1 100644 --- a/iOSClient/Supporting Files/es-NI.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-NI.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-PA.lproj/Localizable.strings b/iOSClient/Supporting Files/es-PA.lproj/Localizable.strings Binary files differindex 9a165ce4d..38f56fcd1 100644 --- a/iOSClient/Supporting Files/es-PA.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-PA.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-PE.lproj/Localizable.strings b/iOSClient/Supporting Files/es-PE.lproj/Localizable.strings Binary files differindex 9a165ce4d..38f56fcd1 100644 --- a/iOSClient/Supporting Files/es-PE.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-PE.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-PR.lproj/Localizable.strings b/iOSClient/Supporting Files/es-PR.lproj/Localizable.strings Binary files differindex 9a165ce4d..38f56fcd1 100644 --- a/iOSClient/Supporting Files/es-PR.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-PR.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-PY.lproj/Localizable.strings b/iOSClient/Supporting Files/es-PY.lproj/Localizable.strings Binary files differindex 9a165ce4d..38f56fcd1 100644 --- a/iOSClient/Supporting Files/es-PY.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-PY.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-SV.lproj/Localizable.strings b/iOSClient/Supporting Files/es-SV.lproj/Localizable.strings Binary files differindex 90d39e042..82e5a4fe4 100644 --- a/iOSClient/Supporting Files/es-SV.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-SV.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es-UY.lproj/Localizable.strings b/iOSClient/Supporting Files/es-UY.lproj/Localizable.strings Binary files differindex 9a165ce4d..38f56fcd1 100644 --- a/iOSClient/Supporting Files/es-UY.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es-UY.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/es.lproj/Localizable.strings b/iOSClient/Supporting Files/es.lproj/Localizable.strings Binary files differindex bdf669973..7c1a6b168 100644 --- a/iOSClient/Supporting Files/es.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/es.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/et_EE.lproj/Localizable.strings b/iOSClient/Supporting Files/et_EE.lproj/Localizable.strings Binary files differindex d48d986f3..62a9e44ba 100644 --- a/iOSClient/Supporting Files/et_EE.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/et_EE.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/eu.lproj/Localizable.strings b/iOSClient/Supporting Files/eu.lproj/Localizable.strings Binary files differindex 5c3281f0d..d29682d4d 100644 --- a/iOSClient/Supporting Files/eu.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/eu.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/fa.lproj/Localizable.strings b/iOSClient/Supporting Files/fa.lproj/Localizable.strings Binary files differindex e4565a330..6871600fe 100644 --- a/iOSClient/Supporting Files/fa.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/fa.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings b/iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings Binary files differindex a83220a0f..0ceea00d6 100644 --- a/iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/fi-FI.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/fr.lproj/Localizable.strings b/iOSClient/Supporting Files/fr.lproj/Localizable.strings Binary files differindex 8de532fe1..a2cbbd6df 100644 --- a/iOSClient/Supporting Files/fr.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/fr.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/gl.lproj/Localizable.strings b/iOSClient/Supporting Files/gl.lproj/Localizable.strings Binary files differindex f6c6e4103..572ab3d38 100644 --- a/iOSClient/Supporting Files/gl.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/gl.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/he.lproj/Localizable.strings b/iOSClient/Supporting Files/he.lproj/Localizable.strings Binary files differindex 5a786ab8c..7f8638fdb 100644 --- a/iOSClient/Supporting Files/he.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/he.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/hr.lproj/Localizable.strings b/iOSClient/Supporting Files/hr.lproj/Localizable.strings Binary files differindex 7f48dc912..be73f62d8 100644 --- a/iOSClient/Supporting Files/hr.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/hr.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/hu.lproj/Localizable.strings b/iOSClient/Supporting Files/hu.lproj/Localizable.strings Binary files differindex 15fbdb74c..9948a18a2 100644 --- a/iOSClient/Supporting Files/hu.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/hu.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/hy.lproj/Localizable.strings b/iOSClient/Supporting Files/hy.lproj/Localizable.strings Binary files differindex d3aa21903..0658a20f3 100644 --- a/iOSClient/Supporting Files/hy.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/hy.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ia.lproj/Localizable.strings b/iOSClient/Supporting Files/ia.lproj/Localizable.strings Binary files differindex b410b18aa..6088d7414 100644 --- a/iOSClient/Supporting Files/ia.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ia.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/id.lproj/Localizable.strings b/iOSClient/Supporting Files/id.lproj/Localizable.strings Binary files differindex b4e4b8af6..fa5e9e25c 100644 --- a/iOSClient/Supporting Files/id.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/id.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/is.lproj/Localizable.strings b/iOSClient/Supporting Files/is.lproj/Localizable.strings Binary files differindex 3b4bde7dc..0cf8252b6 100644 --- a/iOSClient/Supporting Files/is.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/is.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/it.lproj/Localizable.strings b/iOSClient/Supporting Files/it.lproj/Localizable.strings Binary files differindex 787e57e5e..b6ddda0bc 100644 --- a/iOSClient/Supporting Files/it.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/it.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ja-JP.lproj/Localizable.strings b/iOSClient/Supporting Files/ja-JP.lproj/Localizable.strings Binary files differindex efb03baf7..7d0a923a2 100644 --- a/iOSClient/Supporting Files/ja-JP.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ja-JP.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings b/iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings Binary files differindex 113107bb1..cb8799406 100644 --- a/iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ka-GE.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/km.lproj/Localizable.strings b/iOSClient/Supporting Files/km.lproj/Localizable.strings Binary files differindex 0facfb7b2..b15dd3e4d 100644 --- a/iOSClient/Supporting Files/km.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/km.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/kn.lproj/Localizable.strings b/iOSClient/Supporting Files/kn.lproj/Localizable.strings Binary files differindex 1faaa3371..168233cf4 100644 --- a/iOSClient/Supporting Files/kn.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/kn.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ko.lproj/Localizable.strings b/iOSClient/Supporting Files/ko.lproj/Localizable.strings Binary files differindex ad98f7677..4587546a8 100644 --- a/iOSClient/Supporting Files/ko.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ko.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/lb.lproj/Localizable.strings b/iOSClient/Supporting Files/lb.lproj/Localizable.strings Binary files differindex 29dda0854..0ea8a7cb2 100644 --- a/iOSClient/Supporting Files/lb.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/lb.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/lt_LT.lproj/Localizable.strings b/iOSClient/Supporting Files/lt_LT.lproj/Localizable.strings Binary files differindex 3e1607da8..4a7551254 100644 --- a/iOSClient/Supporting Files/lt_LT.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/lt_LT.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/lv.lproj/Localizable.strings b/iOSClient/Supporting Files/lv.lproj/Localizable.strings Binary files differindex 16a051422..d25ea8e5b 100644 --- a/iOSClient/Supporting Files/lv.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/lv.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/mk.lproj/Localizable.strings b/iOSClient/Supporting Files/mk.lproj/Localizable.strings Binary files differindex cffaf9cd1..0271e740e 100644 --- a/iOSClient/Supporting Files/mk.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/mk.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/mn.lproj/Localizable.strings b/iOSClient/Supporting Files/mn.lproj/Localizable.strings Binary files differindex 3fc54dadf..5e148445d 100644 --- a/iOSClient/Supporting Files/mn.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/mn.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ms_MY.lproj/Localizable.strings b/iOSClient/Supporting Files/ms_MY.lproj/Localizable.strings Binary files differindex dacfa3050..f3c90fc08 100644 --- a/iOSClient/Supporting Files/ms_MY.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ms_MY.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings b/iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings Binary files differindex 70a394be4..3e9699061 100644 --- a/iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/nb-NO.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/nl.lproj/Localizable.strings b/iOSClient/Supporting Files/nl.lproj/Localizable.strings Binary files differindex 456e5f27f..1b09093f7 100644 --- a/iOSClient/Supporting Files/nl.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/nl.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/nn_NO.lproj/Localizable.strings b/iOSClient/Supporting Files/nn_NO.lproj/Localizable.strings Binary files differindex c32363ced..9cb42c22e 100644 --- a/iOSClient/Supporting Files/nn_NO.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/nn_NO.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/oc.lproj/Localizable.strings b/iOSClient/Supporting Files/oc.lproj/Localizable.strings Binary files differindex c315b5f6c..0ebd99b85 100644 --- a/iOSClient/Supporting Files/oc.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/oc.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/pl.lproj/Localizable.strings b/iOSClient/Supporting Files/pl.lproj/Localizable.strings Binary files differindex 2f6c15754..b6101bdb5 100644 --- a/iOSClient/Supporting Files/pl.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/pl.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings b/iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings Binary files differindex ef9c4bbc4..aa9c860e8 100644 --- a/iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/pt-BR.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings b/iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings Binary files differindex 70e0f234e..9ee09a509 100644 --- a/iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/pt-PT.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ro.lproj/Localizable.strings b/iOSClient/Supporting Files/ro.lproj/Localizable.strings Binary files differindex 8abafa1dc..512726c3e 100644 --- a/iOSClient/Supporting Files/ro.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ro.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ru.lproj/Localizable.strings b/iOSClient/Supporting Files/ru.lproj/Localizable.strings Binary files differindex 87c5f3d1a..b278ebf42 100644 --- a/iOSClient/Supporting Files/ru.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ru.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/si_LK.lproj/Localizable.strings b/iOSClient/Supporting Files/si_LK.lproj/Localizable.strings Binary files differindex 6af3f96d6..dcaee4b1a 100644 --- a/iOSClient/Supporting Files/si_LK.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/si_LK.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sk-SK.lproj/Localizable.strings b/iOSClient/Supporting Files/sk-SK.lproj/Localizable.strings Binary files differindex 88de87242..ca77d8d6b 100644 --- a/iOSClient/Supporting Files/sk-SK.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sk-SK.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sl.lproj/Localizable.strings b/iOSClient/Supporting Files/sl.lproj/Localizable.strings Binary files differindex 8971d4067..538734e64 100644 --- a/iOSClient/Supporting Files/sl.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sl.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sq.lproj/Localizable.strings b/iOSClient/Supporting Files/sq.lproj/Localizable.strings Binary files differindex c7b81ae54..992d01c86 100644 --- a/iOSClient/Supporting Files/sq.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sq.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sr.lproj/Localizable.strings b/iOSClient/Supporting Files/sr.lproj/Localizable.strings Binary files differindex 01a1d9156..1bbc9644d 100644 --- a/iOSClient/Supporting Files/sr.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sr.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sr@latin.lproj/Localizable.strings b/iOSClient/Supporting Files/sr@latin.lproj/Localizable.strings Binary files differindex 2930cb188..ac8faf8d8 100644 --- a/iOSClient/Supporting Files/sr@latin.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sr@latin.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/sv.lproj/Localizable.strings b/iOSClient/Supporting Files/sv.lproj/Localizable.strings Binary files differindex fc5533093..366f24013 100644 --- a/iOSClient/Supporting Files/sv.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/sv.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ta_LK.lproj/Localizable.strings b/iOSClient/Supporting Files/ta_LK.lproj/Localizable.strings Binary files differindex 428d9349e..a5d7329ce 100644 --- a/iOSClient/Supporting Files/ta_LK.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ta_LK.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/th_TH.lproj/Localizable.strings b/iOSClient/Supporting Files/th_TH.lproj/Localizable.strings Binary files differindex 8db0a203c..7dd5f1ef0 100644 --- a/iOSClient/Supporting Files/th_TH.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/th_TH.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/tr.lproj/Localizable.strings b/iOSClient/Supporting Files/tr.lproj/Localizable.strings Binary files differindex e2d824d66..e7a138ff6 100644 --- a/iOSClient/Supporting Files/tr.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/tr.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ug.lproj/Localizable.strings b/iOSClient/Supporting Files/ug.lproj/Localizable.strings Binary files differindex c2930ff27..4893bdf8e 100644 --- a/iOSClient/Supporting Files/ug.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ug.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/uk.lproj/Localizable.strings b/iOSClient/Supporting Files/uk.lproj/Localizable.strings Binary files differindex c7669fd61..7910abc6c 100644 --- a/iOSClient/Supporting Files/uk.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/uk.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/ur_PK.lproj/Localizable.strings b/iOSClient/Supporting Files/ur_PK.lproj/Localizable.strings Binary files differindex 0fb36d516..ad364ef36 100644 --- a/iOSClient/Supporting Files/ur_PK.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/ur_PK.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/vi.lproj/Localizable.strings b/iOSClient/Supporting Files/vi.lproj/Localizable.strings Binary files differindex 08ea11023..e770090ca 100644 --- a/iOSClient/Supporting Files/vi.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/vi.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/zh-Hans.lproj/Localizable.strings b/iOSClient/Supporting Files/zh-Hans.lproj/Localizable.strings Binary files differindex b5e87b8b3..cf26487b7 100644 --- a/iOSClient/Supporting Files/zh-Hans.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/zh-Hans.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/zh-Hant-TW.lproj/Localizable.strings b/iOSClient/Supporting Files/zh-Hant-TW.lproj/Localizable.strings Binary files differindex 101cf10ad..cbc971e98 100644 --- a/iOSClient/Supporting Files/zh-Hant-TW.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/zh-Hant-TW.lproj/Localizable.strings diff --git a/iOSClient/Supporting Files/zh_HK.lproj/Localizable.strings b/iOSClient/Supporting Files/zh_HK.lproj/Localizable.strings Binary files differindex 18b07df6f..77a2756a5 100644 --- a/iOSClient/Supporting Files/zh_HK.lproj/Localizable.strings +++ b/iOSClient/Supporting Files/zh_HK.lproj/Localizable.strings diff --git a/iOSClient/Synchronize/CCSynchronize.h b/iOSClient/Synchronize/CCSynchronize.h deleted file mode 100644 index aea5a8232..000000000 --- a/iOSClient/Synchronize/CCSynchronize.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// CCSynchronize.h -// Nextcloud -// -// Created by Marino Faggiana on 19/10/16. -// Copyright (c) 2016 Marino Faggiana. All rights reserved. -// -// Author Marino Faggiana <marino.faggiana@nextcloud.com> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// - -#import <Foundation/Foundation.h> - -#import "CCHud.h" - -@class tableMetadata; - -@interface CCSynchronize : NSObject - -+ (CCSynchronize *)sharedSynchronize; - -- (void)readFolder:(NSString *)serverUrl selector:(NSString *)selector account:(NSString *)account; -- (void)readFile:(NSString *)ocId fileName:(NSString *)fileName serverUrl:(NSString *)serverUrl selector:(NSString *)selector account:(NSString *)account; - -- (void)readFolderWithAccount:(NSString *)account serverUrl:(NSString *)serverUrl metadataFolder:(tableMetadata *)metadataFolder metadatas:(NSArray *)metadatas selector:(NSString *)selector; - -- (void)verifyChangeMedatas:(NSArray *)allRecordMetadatas serverUrl:(NSString *)serverUrl account:(NSString *)account withDownload:(BOOL)withDownload; - -@end diff --git a/iOSClient/Synchronize/CCSynchronize.m b/iOSClient/Synchronize/CCSynchronize.m deleted file mode 100644 index 359a1a135..000000000 --- a/iOSClient/Synchronize/CCSynchronize.m +++ /dev/null @@ -1,259 +0,0 @@ -// -// CCSynchronize.m -// Nextcloud -// -// Created by Marino Faggiana on 19/10/16. -// Copyright (c) 2016 Marino Faggiana. All rights reserved. -// -// Author Marino Faggiana <marino.faggiana@nextcloud.com> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// - -#import "CCSynchronize.h" -#import "AppDelegate.h" -#import "CCMain.h" -#import "NCBridgeSwift.h" - -@interface CCSynchronize () -{ -} -@end - -@implementation CCSynchronize - -+ (CCSynchronize *)sharedSynchronize { - - static CCSynchronize *sharedSynchronize; - - @synchronized(self) - { - if (!sharedSynchronize) { - sharedSynchronize = [CCSynchronize new]; - } - return sharedSynchronize; - } -} - -#pragma -------------------------------------------------------------------------------------------- -#pragma mark ===== Read Folder ===== -#pragma -------------------------------------------------------------------------------------------- - -// serverUrl : start -// selector : selectorReadFolder, selectorReadFolderWithDownload -// - -- (void)readFolder:(NSString *)serverUrl selector:(NSString *)selector account:(NSString *)account -{ - [[NCOperationQueue shared] readFolderSyncWithServerUrl:serverUrl selector:selector account:account]; -} - -- (void)readFolderWithAccount:(NSString *)account serverUrl:(NSString *)serverUrl metadataFolder:(tableMetadata *)metadataFolder metadatas:(NSArray *)metadatas selector:(NSString *)selector -{ - AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; - - // Add metadata and update etag Directory - [[NCManageDatabase sharedInstance] addMetadata:metadataFolder]; - [[NCManageDatabase sharedInstance] setDirectoryWithServerUrl:serverUrl serverUrlTo:nil etag:metadataFolder.etag ocId:metadataFolder.ocId fileId:metadataFolder.fileId encrypted:metadataFolder.e2eEncrypted richWorkspace:nil account:appDelegate.activeAccount]; - - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ - - NSMutableArray *metadatasForVerifyChange = [NSMutableArray new]; - NSMutableArray *addMetadatas = [NSMutableArray new]; - - NSArray *recordsInSessions = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND session != ''", account, serverUrl] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO]; - - // ----- Test : (DELETE) ----- - - NSMutableArray *metadatasNotPresents = [NSMutableArray new]; - - NSArray *tableMetadatas = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"account == %@ AND serverUrl == %@ AND session == ''", account, serverUrl] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO]; - - for (tableMetadata *record in tableMetadatas) { - - BOOL ocIdFound = NO; - - for (tableMetadata *metadata in metadatas) { - - if ([record.ocId isEqualToString:metadata.ocId]) { - ocIdFound = YES; - break; - } - } - - if (!ocIdFound) - [metadatasNotPresents addObject:record]; - } - - // delete metadata not present - for (tableMetadata *metadata in metadatasNotPresents) { - - [[NSFileManager defaultManager] removeItemAtPath:[CCUtility getDirectoryProviderStorageOcId:metadata.ocId] error:nil]; - - if (metadata.directory && serverUrl) { - - NSString *dirForDelete = [CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileName]; - - [[NCManageDatabase sharedInstance] deleteDirectoryAndSubDirectoryWithServerUrl:dirForDelete account:account]; - } - - [[NCManageDatabase sharedInstance] deleteMetadataWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", metadata.ocId]]; - [[NCManageDatabase sharedInstance] deleteLocalFileWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", metadata.ocId]]; - } - - // ----- Test : (MODIFY) ----- - - for (tableMetadata *metadata in metadatas) { - - // RECURSIVE DIRECTORY MODE - if (metadata.directory) { - - // Verify if do not exists this Metadata - tableMetadata *result = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", metadata.ocId]]; - - if (!result) - [[NCManageDatabase sharedInstance] addMetadata:metadata]; - - [self readFolder:[CCUtility stringAppendServerUrl:serverUrl addFileName:metadata.fileName] selector:selector account:account]; - - } else { - - if ([selector isEqualToString:selectorReadFolderWithDownload]) { - - // It's in session - BOOL recordInSession = NO; - for (tableMetadata *record in recordsInSessions) { - if ([record.ocId isEqualToString:metadata.ocId]) { - recordInSession = YES; - break; - } - } - - if (recordInSession) - continue; - - // Ohhhh INSERT - [metadatasForVerifyChange addObject:metadata]; - } - - if ([selector isEqualToString:selectorReadFolder]) { - - // Verify if do not exists this Metadata - tableMetadata *result = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", metadata.ocId]]; - - if (!result) - [addMetadatas addObject:metadata]; - } - } - } - - if ([addMetadatas count] > 0) - [[NCManageDatabase sharedInstance] addMetadatas:addMetadatas]; - - if ([metadatasForVerifyChange count] > 0) - [self verifyChangeMedatas:metadatasForVerifyChange serverUrl:serverUrl account:account withDownload:YES]; - }); -} - -#pragma -------------------------------------------------------------------------------------------- -#pragma mark ===== Read File for Folder & Read File===== -#pragma -------------------------------------------------------------------------------------------- - -- (void)readFile:(NSString *)ocId fileName:(NSString *)fileName serverUrl:(NSString *)serverUrl selector:(NSString *)selector account:(NSString *)account -{ - NSString *serverUrlFileName = [NSString stringWithFormat:@"%@/%@", serverUrl, fileName]; - - [[NCNetworking shared] readFileWithServerUrlFileName:serverUrlFileName account:account completion:^(NSString *account, tableMetadata *metadata, NSInteger errorCode, NSString *errorDescription) { - - if (errorCode == 0 && [account isEqualToString:account]) { - - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ - - BOOL withDownload = NO; - - if ([selector isEqualToString:selectorReadFileWithDownload]) - withDownload = YES; - - //Add/Update Metadata - tableMetadata *addMetadata = [[NCManageDatabase sharedInstance] addMetadata:metadata]; - if (addMetadata) - [self verifyChangeMedatas:[[NSArray alloc] initWithObjects:addMetadata, nil] serverUrl:serverUrl account:account withDownload:withDownload]; - }); - - } else if (errorCode == 404) { - - [[NCManageDatabase sharedInstance] deleteMetadataWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", ocId]]; - [[NCManageDatabase sharedInstance] deleteLocalFileWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", ocId]]; - } - }]; -} - -#pragma -------------------------------------------------------------------------------------------- -#pragma mark ===== Verify Metadatas ===== -#pragma -------------------------------------------------------------------------------------------- - -// MULTI THREAD -- (void)verifyChangeMedatas:(NSArray *)allRecordMetadatas serverUrl:(NSString *)serverUrl account:(NSString *)account withDownload:(BOOL)withDownload -{ - NSMutableArray *metadatas = [[NSMutableArray alloc] init]; - - for (tableMetadata *metadata in allRecordMetadatas) { - - BOOL changeRev = NO; - - // change account - if ([metadata.account isEqualToString:account] == NO) - return; - - // no dir - if (metadata.directory) - continue; - - tableLocalFile *localFile = [[NCManageDatabase sharedInstance] getTableLocalFileWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", metadata.ocId]]; - - if (withDownload) { - - if (![localFile.etag isEqualToString:metadata.etag] || ![CCUtility fileProviderStorageExists:metadata.ocId fileNameView:metadata.fileNameView]) - changeRev = YES; - - } else { - - if (localFile && ![localFile.etag isEqualToString:metadata.etag]) // it must be in TableRecord - changeRev = YES; - } - - if (changeRev) { - - // remove & re-create - [[NSFileManager defaultManager] removeItemAtPath:[CCUtility getDirectoryProviderStorageOcId:metadata.ocId] error:nil]; - [CCUtility getDirectoryProviderStorageOcId:metadata.ocId fileNameView:metadata.fileNameView]; - - [metadatas addObject:metadata]; - } - } - - if ([metadatas count]) - [self SynchronizeMetadatas:metadatas withDownload:withDownload]; -} - -// MULTI THREAD -- (void)SynchronizeMetadatas:(NSArray *)metadatas withDownload:(BOOL)withDownload -{ - for (tableMetadata *metadata in metadatas) { - [[NCOperationQueue shared] downloadWithMetadata:metadata selector:selectorDownloadSynchronize setFavorite:false]; - } -} - -@end - diff --git a/iOSClient/Transfers/CCTransfers.m b/iOSClient/Transfers/CCTransfers.m index e7b5d390c..be99ca4a0 100644 --- a/iOSClient/Transfers/CCTransfers.m +++ b/iOSClient/Transfers/CCTransfers.m @@ -155,7 +155,7 @@ UIMenuController *menuController = [UIMenuController sharedMenuController]; - UIMenuItem *startTaskItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"_start_", nil) action:@selector(startTask:)]; + UIMenuItem *startTaskItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"_force_start_", nil) action:@selector(startTask:)]; [menuController setMenuItems:[NSArray arrayWithObjects:startTaskItem, nil]]; @@ -176,7 +176,7 @@ // Detect E2EE NSString *saveserverUrl = @""; - NSArray *metadatasForE2EE = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"status != %d", k_metadataStatusNormal] page:0 limit:0 sorted:@"serverUrl" ascending:NO freeze:YES]; + NSArray *metadatasForE2EE = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"status != %d", k_metadataStatusNormal] page:0 limit:0 sorted:@"serverUrl" ascending:NO]; for (tableMetadata *metadata in metadatasForE2EE) { if (![saveserverUrl isEqualToString:metadata.serverUrl]) { saveserverUrl = metadata.serverUrl; @@ -186,11 +186,9 @@ } } - /* - if (!([metadataForRecognizer.session isEqualToString:k_upload_session_extension]) &&(metadataForRecognizer.status == k_metadataStatusWaitUpload || metadataForRecognizer.status == k_metadataStatusUploading)) { + if ((metadataForRecognizer.status == k_metadataStatusWaitUpload || metadataForRecognizer.status == k_metadataStatusInUpload || metadataForRecognizer.status == k_metadataStatusUploading)) { return YES; } - */ return NO; } @@ -249,10 +247,12 @@ if (metadataForRecognizer.status == k_metadataStatusUploading) { [[NCMainCommon sharedInstance] cancelTransferMetadata:metadataForRecognizer reloadDatasource:false uploadStatusForcedStart:true]; } else { - metadataForRecognizer.status = k_metadataStatusInUpload; - metadataForRecognizer.session = NCCommunicationCommon.shared.sessionIdentifierBackground; + tableMetadata *metadata = [[NCManageDatabase sharedInstance] copyObjectWithMetadata:metadataForRecognizer]; + metadata.status = k_metadataStatusInUpload; + metadata.session = NCCommunicationCommon.shared.sessionIdentifierBackground; - [[NCNetworking shared] uploadWithMetadata:[[NCManageDatabase sharedInstance] addMetadata:metadataForRecognizer] background: true completion:^(NSInteger errorCode, NSString *errorDescription) { }]; + [[NCManageDatabase sharedInstance] addMetadata:metadata]; + [[NCNetworking shared] uploadWithMetadata:metadata background:true completion:^(NSInteger errorCode, NSString *errorDescription) { }]; } } @@ -263,11 +263,13 @@ - (void)reloadDatasource { // test - if (appDelegate.activeAccount.length == 0 || self.view.window == nil) + if (appDelegate.activeAccount.length == 0 || self.view.window == nil) { return; + } + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSArray *recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"(session CONTAINS 'upload') OR (session CONTAINS 'download')"] page:1 limit:100 sorted:@"sessionTaskIdentifier" ascending:NO freeze:YES]; + NSArray *recordsTableMetadata = [[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"(session CONTAINS 'upload') OR (session CONTAINS 'download')"] page:1 limit:100 sorted:@"sessionTaskIdentifier" ascending:NO]; CCSectionDataSourceMetadata *sectionDataSourceTemp = [CCSectionDataSourceMetadata new]; @@ -277,8 +279,6 @@ sectionDataSource = sectionDataSourceTemp; [self.tableView reloadData]; }); - - [[NCNetworking shared] verifyTransfer]; }); } @@ -314,10 +314,10 @@ NSInteger typeOfSession = 0; NSString *sessionDownload = [[NCCommunicationCommon shared] sessionIdentifierDownload]; - NSInteger queueDownload = [[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session == %@", sessionDownload] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO] count]; + NSInteger queueDownload = [[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session == %@", sessionDownload] page:0 limit:0 sorted:@"fileName" ascending:NO] count]; - NSInteger queueUpload = [[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session == %@", NCCommunicationCommon.shared.sessionIdentifierBackground] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO] count]; - NSInteger queueUploadWWan = [[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session == %@", NCCommunicationCommon.shared.sessionIdentifierBackgroundWWan] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO] count]; + NSInteger queueUpload = [[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session == %@", NCCommunicationCommon.shared.sessionIdentifierBackground] page:0 limit:0 sorted:@"fileName" ascending:NO] count]; + NSInteger queueUploadWWan = [[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session == %@", NCCommunicationCommon.shared.sessionIdentifierBackgroundWWan] page:0 limit:0 sorted:@"fileName" ascending:NO] count]; if ([[sectionDataSource.sections objectAtIndex:section] isKindOfClass:[NSString class]]) titleSection = [sectionDataSource.sections objectAtIndex:section]; if ([[sectionDataSource.sections objectAtIndex:section] isKindOfClass:[NSDate class]]) titleSection = [CCUtility getTitleSectionDate:[sectionDataSource.sections objectAtIndex:section]]; @@ -396,7 +396,7 @@ if ([titleSection containsString:@"download"] && titleSection != nil) { NSString *session = [[NCCommunicationCommon shared] sessionIdentifierDownload]; - NSInteger queueDownload = [[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session == %@", session] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO] count]; + NSInteger queueDownload = [[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session == %@", session] page:0 limit:0 sorted:@"fileName" ascending:NO] count]; // element or elements ? if (queueDownload > 1) element_s = NSLocalizedString(@"_elements_",nil); @@ -413,7 +413,7 @@ // Footer Upload if ([titleSection containsString:@"upload"] && ![titleSection containsString:@"wwan"] && titleSection != nil) { - NSInteger queueUpload = [[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session == %@", NCCommunicationCommon.shared.sessionIdentifierBackground] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO] count]; + NSInteger queueUpload = [[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session == %@", NCCommunicationCommon.shared.sessionIdentifierBackground] page:0 limit:0 sorted:@"fileName" ascending:NO] count]; // element or elements ? if (queueUpload > 1) element_s = NSLocalizedString(@"_elements_",nil); @@ -430,7 +430,7 @@ // Footer Upload WWAN if ([titleSection containsString:@"upload"] && [titleSection containsString:@"wwan"] && titleSection != nil) { - NSInteger queueUploadWWan = [[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session == %@", NCCommunicationCommon.shared.sessionIdentifierBackgroundWWan] page:0 limit:0 sorted:@"fileName" ascending:NO freeze:NO] count]; + NSInteger queueUploadWWan = [[[NCManageDatabase sharedInstance] getMetadatasWithPredicate:[NSPredicate predicateWithFormat:@"session == %@", NCCommunicationCommon.shared.sessionIdentifierBackgroundWWan] page:0 limit:0 sorted:@"fileName" ascending:NO] count]; // element or elements ? if (queueUploadWWan > 1) element_s = NSLocalizedString(@"_elements_",nil); diff --git a/iOSClient/Trash/NCTrash.swift b/iOSClient/Trash/NCTrash.swift index 0d92a5b1c..8b03d7bc6 100644 --- a/iOSClient/Trash/NCTrash.swift +++ b/iOSClient/Trash/NCTrash.swift @@ -99,8 +99,8 @@ class NCTrash: UIViewController, UIGestureRecognizerDelegate, NCTrashListCellDel // Datasource & serverUrl if path == "" { - let userID = (appDelegate.activeUserID as NSString).addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlFragmentAllowed) - path = k_dav + "/trashbin/" + userID! + "/trash/" + guard let userID = (appDelegate.activeUserID as NSString).addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlFragmentAllowed) else { return } + path = appDelegate.activeUrl + "/remote.php/dav/trashbin/" + userID + "/trash/" } if (datasource.count == 0) { @@ -664,9 +664,9 @@ extension NCTrash { NCCommunication.shared.listingTrash(showHiddenFiles: false) { (account, items, errorCode, errorDescription) in self.refreshControl.endRefreshing() - if errorCode == 0 && account == self.appDelegate.activeAccount && items != nil { + if errorCode == 0 && account == self.appDelegate.activeAccount { NCManageDatabase.sharedInstance.deleteTrash(filePath: self.path, account: self.appDelegate.activeAccount) - NCManageDatabase.sharedInstance.addTrash(account: account, items: items!) + NCManageDatabase.sharedInstance.addTrash(account: account, items: items) } else if errorCode != 0 { NCContentPresenter.shared.messageNotification("_error_", description: errorDescription, delay: TimeInterval(k_dismissAfterSecond), type: NCContentPresenter.messageType.error, errorCode: errorCode) } else { @@ -690,8 +690,8 @@ extension NCTrash { return } - let fileNameFrom = appDelegate.activeUrl + tableTrash.filePath + tableTrash.fileName - let fileNameTo = appDelegate.activeUrl + k_dav + "/trashbin/" + appDelegate.activeUserID + "/restore/" + tableTrash.fileName + let fileNameFrom = tableTrash.filePath + tableTrash.fileName + let fileNameTo = appDelegate.activeUrl + "/remote.php/dav/trashbin/" + appDelegate.activeUserID + "/restore/" + tableTrash.fileName NCCommunication.shared.moveFileOrFolder(serverUrlFileNameSource: fileNameFrom, serverUrlFileNameDestination: fileNameTo, overwrite: true) { (account, errorCode, errorDescription) in if errorCode == 0 && account == self.appDelegate.activeAccount { @@ -727,7 +727,7 @@ extension NCTrash { return } - let serverUrlFileName = appDelegate.activeUrl + tableTrash.filePath + tableTrash.fileName + let serverUrlFileName = tableTrash.filePath + tableTrash.fileName NCCommunication.shared.deleteFileOrFolder(serverUrlFileName) { (account, errorCode, errorDescription) in if errorCode == 0 && account == self.appDelegate.activeAccount { diff --git a/iOSClient/UploadFromOtherUpp/CCUploadFromOtherUpp.m b/iOSClient/UploadFromOtherUpp/CCUploadFromOtherUpp.m index 2dce99563..9ce0a4b32 100644 --- a/iOSClient/UploadFromOtherUpp/CCUploadFromOtherUpp.m +++ b/iOSClient/UploadFromOtherUpp/CCUploadFromOtherUpp.m @@ -170,7 +170,7 @@ { NSString *fileName = [[NCUtility sharedInstance] createFileName:self.fileNameTextfield.text serverUrl:serverUrlLocal account:appDelegate.activeAccount]; - tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrlLocal url:@"" contentType:@""]; + tableMetadata *metadataForUpload = [[NCManageDatabase sharedInstance] createMetadataWithAccount:appDelegate.activeAccount fileName:fileName ocId:[[NSUUID UUID] UUIDString] serverUrl:serverUrlLocal urlBase:appDelegate.activeUrl url:@"" contentType:@""]; metadataForUpload.session = NCCommunicationCommon.shared.sessionIdentifierBackground; metadataForUpload.sessionSelector = selectorUploadFile; diff --git a/iOSClient/UploadFromOtherUpp/CCUploadFromOtherUpp.storyboard b/iOSClient/UploadFromOtherUpp/CCUploadFromOtherUpp.storyboard index 07500ad92..1fbd2db75 100644 --- a/iOSClient/UploadFromOtherUpp/CCUploadFromOtherUpp.storyboard +++ b/iOSClient/UploadFromOtherUpp/CCUploadFromOtherUpp.storyboard @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES"> <device id="retina4_7" orientation="portrait" appearance="light"/> <dependencies> <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <scenes> @@ -106,7 +106,7 @@ <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xRI-9K-ta8"> <rect key="frame" x="32" y="0.0" width="311" height="62"/> <subviews> - <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="uploadCloud" translatesAutoresizingMaskIntoConstraints="NO" id="lAw-g4-lYL"> + <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cloudUpload" translatesAutoresizingMaskIntoConstraints="NO" id="lAw-g4-lYL"> <rect key="frame" x="16" y="11" width="40" height="40"/> <color key="tintColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <constraints> @@ -191,7 +191,7 @@ </scene> </scenes> <resources> + <image name="cloudUpload" width="425" height="425"/> <image name="folder" width="300" height="300"/> - <image name="uploadCloud" width="25" height="25"/> </resources> </document> diff --git a/iOSClient/Utility/CCUtility.m b/iOSClient/Utility/CCUtility.m index 3d8504086..f4ee8f53e 100644 --- a/iOSClient/Utility/CCUtility.m +++ b/iOSClient/Utility/CCUtility.m @@ -412,19 +412,16 @@ + (BOOL)isEndToEndEnabled:(NSString *)account { - // DISABLE E2EE - return false; - // DISABLE E2EE - BOOL isE2EEEnabled = [[NCManageDatabase sharedInstance] getCapabilitiesServerBoolWithAccount:account elements:NCElementsJSON.shared.capabilitiesE2EEEnabled exists:false]; + NSString* versionE2EE = [[NCManageDatabase sharedInstance] getCapabilitiesServerStringWithAccount:account elements:NCElementsJSON.shared.capabilitiesE2EEApiVersion]; NSString *publicKey = [self getEndToEndPublicKey:account]; NSString *privateKey = [self getEndToEndPrivateKey:account]; NSString *passphrase = [self getEndToEndPassphrase:account]; NSString *publicKeyServer = [self getEndToEndPublicKeyServer:account]; - if (passphrase.length > 0 && privateKey.length > 0 && publicKey.length > 0 && publicKeyServer.length > 0 && isE2EEEnabled) { - + if (passphrase.length > 0 && privateKey.length > 0 && publicKey.length > 0 && publicKeyServer.length > 0 && isE2EEEnabled && [versionE2EE isEqual:k_E2EE_API]) { + return YES; } else { @@ -1435,38 +1432,44 @@ + (void)extractImageVideoFromAssetLocalIdentifierForUpload:(tableMetadata *)metadata notification:(BOOL)notification completion:(void(^)(tableMetadata *newMetadata, NSString* fileNamePath))completion { - tableMetadata *newMetadata = [[NCManageDatabase sharedInstance] copyObjectWithMetadata:metadata]; - tableAccount *tableAccount = [[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", metadata.account]]; + if ([[NCManageDatabase sharedInstance] getAccountWithPredicate:[NSPredicate predicateWithFormat:@"account == %@", metadata.account]] == nil) { + completion(nil, nil); + return; + } + NSString *ocId = metadata.ocId; - if (tableAccount == nil) { + PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:@[metadata.assetLocalIdentifier] options:nil]; + if (!result.count) { if (notification) { - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_uploadedFile object:nil userInfo:@{@"metadata": metadata, @"errorCode": @(k_CCErrorInternalError), @"errorDescription": @"Upload error, account not found"}]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_uploadedFile object:nil userInfo:@{@"metadata": metadata, @"errorCode": @(k_CCErrorInternalError), @"errorDescription": @"_err_asset_not_found_"}]; } completion(nil, nil); return; } - PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:@[metadata.assetLocalIdentifier] options:nil]; - if (!result.count) { + PHAsset *asset = result[0]; + NSDate *creationDate = asset.creationDate; + NSDate *modificationDate = asset.modificationDate; + NSArray *resourceArray = [PHAssetResource assetResourcesForAsset:asset]; + BOOL isLocallayAvailable = [[resourceArray.firstObject valueForKey:@"locallyAvailable"] boolValue]; + if (!isLocallayAvailable) { if (notification) { - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_uploadedFile object:nil userInfo:@{@"metadata": metadata, @"errorCode": @(k_CCErrorInternalError), @"errorDescription": @"Error photo/video not found, remove from upload"}]; + [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:k_notificationCenter_uploadedFile object:nil userInfo:@{@"metadata": metadata, @"errorCode": @(k_CCErrorInternalError), @"errorDescription": @"_err_asset_not_found_locally_"}]; } completion(nil, nil); return; } - + long fileSize = [[resourceArray.firstObject valueForKey:@"fileSize"] longValue]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - - PHAsset *asset = result[0]; - NSDate *creationDate = asset.creationDate; // IMAGE if (asset.mediaType == PHAssetMediaTypeImage) { PHImageRequestOptions *options = [PHImageRequestOptions new]; - options.networkAccessAllowed = YES; // iCloud + options.networkAccessAllowed = NO; // iCloud options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; options.synchronous = YES; options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) { @@ -1485,6 +1488,12 @@ [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) { + tableMetadata *newMetadata = metadata; + tableMetadata *metadataTmp = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", ocId]]; + if (metadataTmp != nil) { + newMetadata = [[NCManageDatabase sharedInstance] copyObjectWithMetadata:metadataTmp]; + } + NSError *error = nil; NSString *extensionAsset = [[[asset valueForKey:@"filename"] pathExtension] uppercaseString]; NSString *fileName = metadata.fileNameView; @@ -1504,11 +1513,6 @@ [[NSFileManager defaultManager]removeItemAtPath:fileNamePath error:nil]; [imageData writeToFile:fileNamePath options:NSDataWritingAtomic error:&error]; - NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:fileNamePath error:nil]; - - newMetadata.creationDate = creationDate; - newMetadata.date = attributes[NSFileModificationDate]; - newMetadata.size = [attributes[NSFileSize] longValue]; if (newMetadata.e2eEncrypted) { newMetadata.fileNameView = fileName; @@ -1516,7 +1520,11 @@ newMetadata.fileNameView = fileName; newMetadata.fileName = fileName; } - + + newMetadata.creationDate = creationDate; + newMetadata.date = modificationDate; + newMetadata.size = fileSize; + completion(newMetadata, fileNamePath); }]; } @@ -1525,7 +1533,7 @@ if (asset.mediaType == PHAssetMediaTypeVideo) { PHVideoRequestOptions *options = [PHVideoRequestOptions new]; - options.networkAccessAllowed = YES; + options.networkAccessAllowed = NO; options.version = PHVideoRequestOptionsVersionOriginal; options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) { @@ -1543,7 +1551,13 @@ [[PHImageManager defaultManager] requestAVAssetForVideo:asset options:options resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) { if ([asset isKindOfClass:[AVURLAsset class]]) { - + + tableMetadata *newMetadata = metadata; + tableMetadata *metadataTmp = [[NCManageDatabase sharedInstance] getMetadataWithPredicate:[NSPredicate predicateWithFormat:@"ocId == %@", ocId]]; + if (metadataTmp != nil) { + newMetadata = [[NCManageDatabase sharedInstance] copyObjectWithMetadata:metadataTmp]; + } + NSString *fileNamePath = [NSTemporaryDirectory() stringByAppendingString:newMetadata.fileNameView]; NSURL *fileNamePathURL = [[NSURL alloc] initFileURLWithPath:fileNamePath]; NSError *error = nil; @@ -1562,14 +1576,10 @@ completion(nil, nil); } else { - - NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:fileNamePath error:nil]; newMetadata.creationDate = creationDate; - if (attributes[NSFileModificationDate]) { - newMetadata.date = attributes[NSFileModificationDate]; - } - newMetadata.size = [attributes[NSFileSize] longValue]; + newMetadata.date = modificationDate; + newMetadata.size = fileSize; completion(newMetadata, fileNamePath); } @@ -1593,7 +1603,6 @@ + (BOOL)isFolderEncrypted:(NSString *)serverUrl e2eEncrypted:(BOOL)e2eEncrypted account:(NSString *)account { - if (e2eEncrypted) { return true; @@ -1618,8 +1627,8 @@ #pragma mark ===== Share Permissions ===== #pragma -------------------------------------------------------------------------------------------- -+ (NSInteger) getPermissionsValueByCanEdit:(BOOL)canEdit andCanCreate:(BOOL)canCreate andCanChange:(BOOL)canChange andCanDelete:(BOOL)canDelete andCanShare:(BOOL)canShare andIsFolder:(BOOL) isFolder { - ++ (NSInteger) getPermissionsValueByCanEdit:(BOOL)canEdit andCanCreate:(BOOL)canCreate andCanChange:(BOOL)canChange andCanDelete:(BOOL)canDelete andCanShare:(BOOL)canShare andIsFolder:(BOOL) isFolder +{ NSInteger permissionsValue = k_read_share_permission; if (canEdit && !isFolder) { diff --git a/iOSClient/Utility/NCContentPresenter.swift b/iOSClient/Utility/NCContentPresenter.swift index c7d535ae0..b71b5976a 100644 --- a/iOSClient/Utility/NCContentPresenter.swift +++ b/iOSClient/Utility/NCContentPresenter.swift @@ -64,22 +64,25 @@ class NCContentPresenter: NSObject { //MARK: - Message - @objc func messageNotification(_ title: String, description: String?, delay: TimeInterval, type: messageType, errorCode: Int) { + @objc func messageNotification(_ title: String, description: String?, delay: TimeInterval, type: messageType, errorCode: Int, forced: Bool = false) { // No notification message - if errorCode == -999 { return } // Cancelled transfer - else if errorCode == 200 { return } // Transfer stopped - else if errorCode == 207 { return } // WebDAV multistatus - else if errorCode == 423 { return } // WebDAV locked - else if errorCode == -1001 { return } // Time out - else if errorCode == -1005 { return } // Connection lost - else if errorCode == 0 && type == messageType.error { return } - - // No repeat message for: - if errorCode == lastErrorCode { - if errorCode == Int(CFNetworkErrors.cfurlErrorNotConnectedToInternet.rawValue) { return } - } else { - lastErrorCode = errorCode + if forced == false { + + if errorCode == -999 { return } // Cancelled transfer + else if errorCode == 200 { return } // Transfer stopped + else if errorCode == 207 { return } // WebDAV multistatus + else if errorCode == 423 { return } // WebDAV locked + else if errorCode == -1001 { return } // Time out + else if errorCode == -1005 { return } // Connection lost + else if errorCode == 0 && type == messageType.error { return } + + // No repeat message for: + if errorCode == lastErrorCode { + if errorCode == Int(CFNetworkErrors.cfurlErrorNotConnectedToInternet.rawValue) { return } + } else { + lastErrorCode = errorCode + } } DispatchQueue.main.async { diff --git a/iOSClient/Utility/NCUtility.swift b/iOSClient/Utility/NCUtility.swift index 0fa988a3f..3c319d14a 100644 --- a/iOSClient/Utility/NCUtility.swift +++ b/iOSClient/Utility/NCUtility.swift @@ -305,31 +305,7 @@ class NCUtility: NSObject { } } } - - @objc func bestFittingFont(for text: String, in bounds: CGRect, fontDescriptor: UIFontDescriptor) -> UIFont { - - let constrainingDimension = min(bounds.width, bounds.height) - let properBounds = CGRect(origin: .zero, size: bounds.size) - var attributes: [NSAttributedString.Key: Any] = [:] - let infiniteBounds = CGSize(width: CGFloat.infinity, height: CGFloat.infinity) - var bestFontSize: CGFloat = constrainingDimension - - for fontSize in stride(from: bestFontSize, through: 0, by: -1) { - let newFont = UIFont(descriptor: fontDescriptor, size: fontSize) - attributes[.font] = newFont - - let currentFrame = text.boundingRect(with: infiniteBounds, options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: attributes, context: nil) - - if properBounds.contains(currentFrame) { - bestFontSize = fontSize - break - } - } - - return UIFont(descriptor: fontDescriptor, size: bestFontSize) - } - @objc func isRichDocument(_ metadata: tableMetadata) -> Bool { guard let mimeType = CCUtility.getMimeType(metadata.fileNameView) else { @@ -532,13 +508,22 @@ class NCUtility: NSObject { } // Delete Asset on Photos album - @objc func deleteAssetLocalIdentifiers(account: String, sessionSelector: String) { + @objc func deleteAssetLocalIdentifiers(account: String, sessionSelector: String, completition: @escaping () -> ()) { - if UIApplication.shared.applicationState != .active { return } + if UIApplication.shared.applicationState != .active { + completition() + return + } let metadatasSessionUpload = NCManageDatabase.sharedInstance.getMetadatas(predicate: NSPredicate(format: "account == %@ AND session CONTAINS[cd] %@", account, "upload")) - if metadatasSessionUpload?.count ?? 0 > 0 { return } + if metadatasSessionUpload.count > 0 { + completition() + return + } let localIdentifiers = NCManageDatabase.sharedInstance.getAssetLocalIdentifiersUploaded(account: account, sessionSelector: sessionSelector) - if localIdentifiers.count == 0 { return } + if localIdentifiers.count == 0 { + completition() + return + } let assets = PHAsset.fetchAssets(withLocalIdentifiers: localIdentifiers, options: nil) PHPhotoLibrary.shared().performChanges({ @@ -546,6 +531,7 @@ class NCUtility: NSObject { }, completionHandler: { success, error in DispatchQueue.main.async { NCManageDatabase.sharedInstance.clearAssetLocalIdentifiers(localIdentifiers, account: account) + completition() } }) } diff --git a/iOSClient/Viewer/NCViewerImage/NCViewerImageCommon.swift b/iOSClient/Viewer/NCViewerImage/NCViewerImageCommon.swift index 65d681e54..25dd74776 100644 --- a/iOSClient/Viewer/NCViewerImage/NCViewerImageCommon.swift +++ b/iOSClient/Viewer/NCViewerImage/NCViewerImageCommon.swift @@ -54,18 +54,15 @@ class NCViewerImageCommon: NSObject { var datasourceSorted = "" var datasourceAscending = true (_, datasourceSorted, datasourceAscending, _, _) = NCUtility.sharedInstance.getLayoutForView(key: k_layout_view_offline) - if let files = NCManageDatabase.sharedInstance.getTableLocalFiles(predicate: NSPredicate(format: "account == %@ AND offline == true", metadata.account), sorted: datasourceSorted, ascending: datasourceAscending) { - var ocIds: [String] = [] - for file: tableLocalFile in files { - ocIds.append(file.ocId) - } - return NCManageDatabase.sharedInstance.getMetadatasViewer(predicate: NSPredicate(format: "account == %@ AND ocId IN %@ AND (typeFile == %@ || typeFile == %@ || typeFile == %@)", metadata.account, ocIds, k_metadataTypeFile_image, k_metadataTypeFile_video, k_metadataTypeFile_audio), sorted: datasourceSorted, ascending: datasourceAscending) + let files = NCManageDatabase.sharedInstance.getTableLocalFiles(predicate: NSPredicate(format: "account == %@ AND offline == true", metadata.account), sorted: datasourceSorted, ascending: datasourceAscending) + var ocIds: [String] = [] + for file: tableLocalFile in files { + ocIds.append(file.ocId) } + return NCManageDatabase.sharedInstance.getMetadatasViewer(predicate: NSPredicate(format: "account == %@ AND ocId IN %@ AND (typeFile == %@ || typeFile == %@ || typeFile == %@)", metadata.account, ocIds, k_metadataTypeFile_image, k_metadataTypeFile_video, k_metadataTypeFile_audio), sorted: datasourceSorted, ascending: datasourceAscending) } else { return NCManageDatabase.sharedInstance.getMetadatasViewer(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (typeFile == %@ || typeFile == %@ || typeFile == %@)", metadata.account, metadata.serverUrl, k_metadataTypeFile_image, k_metadataTypeFile_video, k_metadataTypeFile_audio), sorted: CCUtility.getOrderSettings(), ascending: CCUtility.getAscendingSettings()) } - - return nil } func getThumbnailImage(metadata: tableMetadata) -> UIImage? { |