From aa83b5a0ca30736b2800833bcc6149dcbe8436fa Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Sat, 11 Nov 2017 21:15:20 -0800 Subject: [PATCH] Introducing RCTSurfaceBackedComponent Summary: RCTSurfaceBackedComponent is ComponentKit component represents a React Native Surface created (and stored in the state) with given `bridge`, `moduleName`, and `properties`. Differential Revision: D6217103 fbshipit-source-id: 2849f68e1975562cd47851bda232e389705b4229 --- .../RCTSurfaceBackedComponent.h | 28 ++++++++ .../RCTSurfaceBackedComponent.mm | 68 +++++++++++++++++++ .../RCTSurfaceBackedComponentState.h | 20 ++++++ .../RCTSurfaceBackedComponentState.mm | 30 ++++++++ 4 files changed, 146 insertions(+) create mode 100644 Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.h create mode 100644 Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.mm create mode 100644 Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.h create mode 100644 Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.mm diff --git a/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.h b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.h new file mode 100644 index 000000000..49017bda5 --- /dev/null +++ b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.h @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import +#import +#import + +@class RCTBridge; + +/** + * ComponentKit component represents a React Native Surface created + * (and stored in the state) with given `bridge`, `moduleName`, + * and `properties`. + */ +@interface RCTSurfaceBackedComponent : CKCompositeComponent + ++ (instancetype)newWithBridge:(RCTBridge *)bridge + moduleName:(NSString *)moduleName + properties:(NSDictionary *)properties + options:(RCTSurfaceHostingComponentOptions)options; + +@end diff --git a/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.mm b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.mm new file mode 100644 index 000000000..74e03c5cf --- /dev/null +++ b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponent.mm @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "RCTSurfaceBackedComponent.h" + +#import + +#import +#import +#import +#import + +#import "RCTSurfaceBackedComponentState.h" + +@implementation RCTSurfaceBackedComponent + ++ (id)initialState +{ + return [RCTSurfaceBackedComponentState new]; +} + ++ (instancetype)newWithBridge:(RCTBridge *)bridge + moduleName:(NSString *)moduleName + properties:(NSDictionary *)properties + options:(RCTSurfaceHostingComponentOptions)options +{ + CKComponentScope scope(self, moduleName); + + RCTSurfaceBackedComponentState *state = scope.state(); + + if (state.surface == nil || state.surface.bridge != bridge || ![state.surface.moduleName isEqualToString:moduleName]) { + RCTSurface *surface = + [[RCTSurface alloc] initWithBridge:bridge + moduleName:moduleName + initialProperties:properties]; + + state = [RCTSurfaceBackedComponentState newWithSurface:surface]; + + CKComponentScope::replaceState(scope, state); + } + else { + if (![state.surface.properties isEqualToDictionary:properties]) { + state.surface.properties = properties; + } + } + + RCTSurfaceHostingComponent *surfaceHostingComponent = + [RCTSurfaceHostingComponent newWithSurface:state.surface + options:options]; + + CKComponent *component; + if (options.activityIndicatorComponentFactory == nil || state.surface.stage & RCTSurfaceStageSurfaceDidInitialLayout) { + component = surfaceHostingComponent; + } else { + component = [CKOverlayLayoutComponent newWithComponent:surfaceHostingComponent + overlay:options.activityIndicatorComponentFactory()]; + } + + return [super newWithComponent:component]; +} + +@end diff --git a/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.h b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.h new file mode 100644 index 000000000..819d927d0 --- /dev/null +++ b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.h @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +@class RCTSurface; + +@interface RCTSurfaceBackedComponentState: NSObject + +@property (atomic, readonly, strong) RCTSurface *surface; + ++ (instancetype)newWithSurface:(RCTSurface *)surface; + +@end diff --git a/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.mm b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.mm new file mode 100644 index 000000000..25d1819a5 --- /dev/null +++ b/Libraries/SurfaceBackedComponent/RCTSurfaceBackedComponentState.mm @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "RCTSurfaceBackedComponentState.h" + +#import + +@implementation RCTSurfaceBackedComponentState + ++ (instancetype)newWithSurface:(RCTSurface *)surface +{ + return [[self alloc] initWithSurface:surface]; +} + +- (instancetype)initWithSurface:(RCTSurface *)surface +{ + if (self == [super init]) { + _surface = surface; + } + + return self; +} + +@end