-
-
Notifications
You must be signed in to change notification settings - Fork 839
/
RNMBXViewportComponentView.mm
126 lines (101 loc) · 3.97 KB
/
RNMBXViewportComponentView.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#ifdef RCT_NEW_ARCH_ENABLED
#import "RNMBXViewportComponentView.h"
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnmapbox_maps_specs/ComponentDescriptors.h>
#import <react/renderer/components/rnmapbox_maps_specs/EventEmitters.h>
#import <react/renderer/components/rnmapbox_maps_specs/Props.h>
#import <react/renderer/components/rnmapbox_maps_specs/RCTComponentViewHelpers.h>
#import "rnmapbox_maps-Swift.pre.h"
#import "RCTFollyConvert.h"
// TODO: use generated RNMBXViewportEventEmitter, but need 0.73+ for dynamic support
class RNMBXViewportEventEmitter : public facebook::react::ViewEventEmitter {
public:
using facebook::react::ViewEventEmitter::ViewEventEmitter;
struct OnStatusChanged {
std::string type;
folly::dynamic payload;
};
void onStatusChanged(OnStatusChanged $event) const {
dispatchEvent("statusChanged", [$event=std::move($event)](facebook::jsi::Runtime &runtime) {
auto $payload = facebook::jsi::Object(runtime);
$payload.setProperty(runtime, "type", $event.type);
$payload.setProperty(runtime, "payload", facebook::jsi::valueFromDynamic(runtime, $event.payload));
return $payload;
});
}
};
using namespace facebook::react;
NSNumber* convertDynamicToOptional_boolean(const folly::dynamic &dyn, NSString* propertyName) {
switch (dyn.type()) {
case folly::dynamic::NULLT:
return NULL;
case folly::dynamic::BOOL:
return [NSNumber numberWithBool:dyn.getBool()];
default:
std::stringstream ss;
ss << dyn;
[RNMBXLogger error:[NSString stringWithFormat:@"Property %@ expected to be a boolean or nil but was: $d",
propertyName,
ss.str().c_str()
]];
return NULL;
}
}
@implementation RNMBXViewportComponentView {
RNMBXViewport *_view;
}
// Needed because of this: https://github.com/facebook/react-native/pull/37274
+ (void)load
{
[super load];
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
static const auto defaultProps = std::make_shared<const RNMBXViewportProps>();
_props = defaultProps;
_view = [[RNMBXViewport alloc] init];
[self prepareView];
self.contentView = _view;
}
return self;
}
- (void)prepareView
{
__weak __typeof__(self) weakSelf = self;
[_view setOnStatusChanged:^(NSDictionary* event) {
__typeof__(self) strongSelf = weakSelf;
if (strongSelf != nullptr && strongSelf->_eventEmitter != nullptr) {
auto type = std::string([[event objectForKey:@"type"] UTF8String]);
auto payload = convertIdToFollyDynamic([event objectForKey:@"payload"]);
::RNMBXViewportEventEmitter::OnStatusChanged event = {type, payload};
std::reinterpret_pointer_cast<const ::RNMBXViewportEventEmitter>(strongSelf->_eventEmitter)->onStatusChanged(event);
}
}];
}
#pragma mark - RCTComponentViewProtocol
+ (ComponentDescriptorProvider)componentDescriptorProvider
{
return concreteComponentDescriptorProvider<RNMBXViewportComponentDescriptor>();
}
- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps
{
const auto &oldViewProps = static_cast<const RNMBXViewportProps &>(*oldProps);
const auto &newViewProps = static_cast<const RNMBXViewportProps &>(*props);
if (!oldProps.get() || oldViewProps.transitionsToIdleUponUserInteraction != newViewProps.transitionsToIdleUponUserInteraction) {
_view.transitionsToIdleUponUserInteraction = convertDynamicToOptional_boolean(newViewProps.transitionsToIdleUponUserInteraction, @"transitionsToIdleUponUserInteraction");
}
if (!oldProps.get() ||
oldViewProps.hasStatusChanged !=
newViewProps.hasStatusChanged) {
_view.hasStatusChanged = newViewProps.hasStatusChanged;
}
[super updateProps:props oldProps:oldProps];
}
@end
Class<RCTComponentViewProtocol> RNMBXViewportCls(void)
{
return RNMBXViewportComponentView.class;
}
#endif // RCT_NEW_ARCH_ENABLED