This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
247 lines
7.8 KiB
247 lines
7.8 KiB
/** |
|
* Copyright (c) 2015-present, Facebook, Inc. |
|
* |
|
* This source code is licensed under the MIT license found in the |
|
* LICENSE file in the root directory of this source tree. |
|
*/ |
|
#import "RCTNativeAnimatedModule.h" |
|
|
|
#import "RCTNativeAnimatedNodesManager.h" |
|
|
|
typedef void (^AnimatedOperation)(RCTNativeAnimatedNodesManager *nodesManager); |
|
|
|
@implementation RCTNativeAnimatedModule |
|
{ |
|
RCTNativeAnimatedNodesManager *_nodesManager; |
|
|
|
// Oparations called after views have been updated. |
|
NSMutableArray<AnimatedOperation> *_operations; |
|
// Operations called before views have been updated. |
|
NSMutableArray<AnimatedOperation> *_preOperations; |
|
} |
|
|
|
RCT_EXPORT_MODULE(); |
|
|
|
- (void)invalidate |
|
{ |
|
[_nodesManager stopAnimationLoop]; |
|
[self.bridge.eventDispatcher removeDispatchObserver:self]; |
|
[self.bridge.uiManager.observerCoordinator removeObserver:self]; |
|
} |
|
|
|
- (dispatch_queue_t)methodQueue |
|
{ |
|
// This module needs to be on the same queue as the UIManager to avoid |
|
// having to lock `_operations` and `_preOperations` since `uiManagerWillPerformMounting` |
|
// will be called from that queue. |
|
return RCTGetUIManagerQueue(); |
|
} |
|
|
|
- (void)setBridge:(RCTBridge *)bridge |
|
{ |
|
[super setBridge:bridge]; |
|
|
|
_nodesManager = [[RCTNativeAnimatedNodesManager alloc] initWithUIManager:self.bridge.uiManager]; |
|
_operations = [NSMutableArray new]; |
|
_preOperations = [NSMutableArray new]; |
|
|
|
[bridge.eventDispatcher addDispatchObserver:self]; |
|
[bridge.uiManager.observerCoordinator addObserver:self]; |
|
} |
|
|
|
#pragma mark -- API |
|
|
|
RCT_EXPORT_METHOD(createAnimatedNode:(nonnull NSNumber *)tag |
|
config:(NSDictionary<NSString *, id> *)config) |
|
{ |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager createAnimatedNode:tag config:config]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(connectAnimatedNodes:(nonnull NSNumber *)parentTag |
|
childTag:(nonnull NSNumber *)childTag) |
|
{ |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager connectAnimatedNodes:parentTag childTag:childTag]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(disconnectAnimatedNodes:(nonnull NSNumber *)parentTag |
|
childTag:(nonnull NSNumber *)childTag) |
|
{ |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager disconnectAnimatedNodes:parentTag childTag:childTag]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(startAnimatingNode:(nonnull NSNumber *)animationId |
|
nodeTag:(nonnull NSNumber *)nodeTag |
|
config:(NSDictionary<NSString *, id> *)config |
|
endCallback:(RCTResponseSenderBlock)callBack) |
|
{ |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager startAnimatingNode:animationId nodeTag:nodeTag config:config endCallback:callBack]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(stopAnimation:(nonnull NSNumber *)animationId) |
|
{ |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager stopAnimation:animationId]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(setAnimatedNodeValue:(nonnull NSNumber *)nodeTag |
|
value:(nonnull NSNumber *)value) |
|
{ |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager setAnimatedNodeValue:nodeTag value:value]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(setAnimatedNodeOffset:(nonnull NSNumber *)nodeTag |
|
offset:(nonnull NSNumber *)offset) |
|
{ |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager setAnimatedNodeOffset:nodeTag offset:offset]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(flattenAnimatedNodeOffset:(nonnull NSNumber *)nodeTag) |
|
{ |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager flattenAnimatedNodeOffset:nodeTag]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(extractAnimatedNodeOffset:(nonnull NSNumber *)nodeTag) |
|
{ |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager extractAnimatedNodeOffset:nodeTag]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(connectAnimatedNodeToView:(nonnull NSNumber *)nodeTag |
|
viewTag:(nonnull NSNumber *)viewTag) |
|
{ |
|
NSString *viewName = [self.bridge.uiManager viewNameForReactTag:viewTag]; |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager connectAnimatedNodeToView:nodeTag viewTag:viewTag viewName:viewName]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(disconnectAnimatedNodeFromView:(nonnull NSNumber *)nodeTag |
|
viewTag:(nonnull NSNumber *)viewTag) |
|
{ |
|
[self addPreOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager restoreDefaultValues:nodeTag]; |
|
}]; |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager disconnectAnimatedNodeFromView:nodeTag viewTag:viewTag]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(dropAnimatedNode:(nonnull NSNumber *)tag) |
|
{ |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager dropAnimatedNode:tag]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(startListeningToAnimatedNodeValue:(nonnull NSNumber *)tag) |
|
{ |
|
__weak id<RCTValueAnimatedNodeObserver> valueObserver = self; |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager startListeningToAnimatedNodeValue:tag valueObserver:valueObserver]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(stopListeningToAnimatedNodeValue:(nonnull NSNumber *)tag) |
|
{ |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager stopListeningToAnimatedNodeValue:tag]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(addAnimatedEventToView:(nonnull NSNumber *)viewTag |
|
eventName:(nonnull NSString *)eventName |
|
eventMapping:(NSDictionary<NSString *, id> *)eventMapping) |
|
{ |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager addAnimatedEventToView:viewTag eventName:eventName eventMapping:eventMapping]; |
|
}]; |
|
} |
|
|
|
RCT_EXPORT_METHOD(removeAnimatedEventFromView:(nonnull NSNumber *)viewTag |
|
eventName:(nonnull NSString *)eventName |
|
animatedNodeTag:(nonnull NSNumber *)animatedNodeTag) |
|
{ |
|
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) { |
|
[nodesManager removeAnimatedEventFromView:viewTag eventName:eventName animatedNodeTag:animatedNodeTag]; |
|
}]; |
|
} |
|
|
|
#pragma mark -- Batch handling |
|
|
|
- (void)addOperationBlock:(AnimatedOperation)operation |
|
{ |
|
[_operations addObject:operation]; |
|
} |
|
|
|
- (void)addPreOperationBlock:(AnimatedOperation)operation |
|
{ |
|
[_preOperations addObject:operation]; |
|
} |
|
|
|
#pragma mark - RCTUIManagerObserver |
|
|
|
- (void)uiManagerWillPerformMounting:(RCTUIManager *)uiManager |
|
{ |
|
if (_preOperations.count == 0 && _operations.count == 0) { |
|
return; |
|
} |
|
|
|
NSArray<AnimatedOperation> *preOperations = _preOperations; |
|
NSArray<AnimatedOperation> *operations = _operations; |
|
_preOperations = [NSMutableArray new]; |
|
_operations = [NSMutableArray new]; |
|
|
|
[uiManager prependUIBlock:^(__unused RCTUIManager *manager, __unused NSDictionary<NSNumber *, UIView *> *viewRegistry) { |
|
for (AnimatedOperation operation in preOperations) { |
|
operation(self->_nodesManager); |
|
} |
|
}]; |
|
|
|
[uiManager addUIBlock:^(__unused RCTUIManager *manager, __unused NSDictionary<NSNumber *, UIView *> *viewRegistry) { |
|
for (AnimatedOperation operation in operations) { |
|
operation(self->_nodesManager); |
|
} |
|
|
|
[self->_nodesManager updateAnimations]; |
|
}]; |
|
} |
|
|
|
#pragma mark -- Events |
|
|
|
- (NSArray<NSString *> *)supportedEvents |
|
{ |
|
return @[@"onAnimatedValueUpdate"]; |
|
} |
|
|
|
- (void)animatedNode:(RCTValueAnimatedNode *)node didUpdateValue:(CGFloat)value |
|
{ |
|
[self sendEventWithName:@"onAnimatedValueUpdate" |
|
body:@{@"tag": node.nodeTag, @"value": @(value)}]; |
|
} |
|
|
|
- (void)eventDispatcherWillDispatchEvent:(id<RCTEvent>)event |
|
{ |
|
// Events can be dispatched from any queue so we have to make sure handleAnimatedEvent |
|
// is run from the main queue. |
|
RCTExecuteOnMainQueue(^{ |
|
[self->_nodesManager handleAnimatedEvent:event]; |
|
}); |
|
} |
|
|
|
@end
|
|
|