Skip to content

Commit

Permalink
Use published version of React Native. (#379)
Browse files Browse the repository at this point in the history
This diff removes the React Native fork and monkey patches React Native instead.

You'll probably need to run these commands:
```
rm -rf node_modules
yarn cache clean
yarn
```
  • Loading branch information
neerajwahi authored Mar 6, 2017
1 parent d5d76a8 commit 4b95b12
Show file tree
Hide file tree
Showing 20 changed files with 599 additions and 202 deletions.
30 changes: 30 additions & 0 deletions ios/ZulipMobile.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
A155C0061DD8E7A800A8B695 /* libRCTCameraRoll.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A155BFEC1DD8E54100A8B695 /* libRCTCameraRoll.a */; };
C2FB87564E22416A9EDEABD3 /* EvilIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AEF58326BC25479294083E9C /* EvilIcons.ttf */; };
C478B42A63D649EFA2CFD12D /* SimpleLineIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9E53FD60A6D0409A8E58DCB5 /* SimpleLineIcons.ttf */; };
CF15A6B21E5C0C8A003EA77F /* UIView+Tag.m in Sources */ = {isa = PBXBuildFile; fileRef = CF15A6B11E5C0C8A003EA77F /* UIView+Tag.m */; };
CF15A6B61E5C56E5003EA77F /* OptimizedGifDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = CF15A6B51E5C56E5003EA77F /* OptimizedGifDecoder.m */; };
CF1953241E5BE67D00B14FF0 /* AnchorScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = CF1953231E5BE67D00B14FF0 /* AnchorScrollView.m */; };
CF1953261E5BF2E000B14FF0 /* AnchorScrollViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CF1953251E5BF2E000B14FF0 /* AnchorScrollViewManager.m */; };
CF19532E1E5C062B00B14FF0 /* TaggedViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CF19532D1E5C062B00B14FF0 /* TaggedViewManager.m */; };
D6D40984ED07473499B3F0C9 /* libRNDeviceInfo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D5664A74FA8048439CBAB734 /* libRNDeviceInfo.a */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -263,6 +268,16 @@
ACCD980949044096B1BAD249 /* RNDeviceInfo.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RNDeviceInfo.xcodeproj; path = "../node_modules/react-native-device-info/RNDeviceInfo.xcodeproj"; sourceTree = "<group>"; };
AEF58326BC25479294083E9C /* EvilIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = EvilIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf"; sourceTree = "<group>"; };
C9B0BDEA40534DFA9BDC4C75 /* FontAwesome.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = FontAwesome.ttf; path = "../node_modules/react-native-vector-icons/Fonts/FontAwesome.ttf"; sourceTree = "<group>"; };
CF15A6B11E5C0C8A003EA77F /* UIView+Tag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIView+Tag.m"; path = "ZulipMobile/UIView+Tag.m"; sourceTree = "<group>"; };
CF15A6B31E5C21CB003EA77F /* AnchorScrollViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnchorScrollViewManager.h; path = ZulipMobile/AnchorScrollViewManager.h; sourceTree = "<group>"; };
CF15A6B51E5C56E5003EA77F /* OptimizedGifDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OptimizedGifDecoder.m; path = ZulipMobile/OptimizedGifDecoder.m; sourceTree = "<group>"; };
CF15A6B71E5C56F8003EA77F /* OptimizedGifDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptimizedGifDecoder.h; path = ZulipMobile/OptimizedGifDecoder.h; sourceTree = "<group>"; };
CF1953221E5BE66800B14FF0 /* AnchorScrollView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AnchorScrollView.h; path = ZulipMobile/AnchorScrollView.h; sourceTree = "<group>"; };
CF1953231E5BE67D00B14FF0 /* AnchorScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AnchorScrollView.m; path = ZulipMobile/AnchorScrollView.m; sourceTree = "<group>"; };
CF1953251E5BF2E000B14FF0 /* AnchorScrollViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AnchorScrollViewManager.m; path = ZulipMobile/AnchorScrollViewManager.m; sourceTree = "<group>"; };
CF1953291E5C05BF00B14FF0 /* UIView+Tag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIView+Tag.h"; path = "ZulipMobile/UIView+Tag.h"; sourceTree = "<group>"; };
CF19532C1E5C062B00B14FF0 /* TaggedViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaggedViewManager.h; path = ZulipMobile/TaggedViewManager.h; sourceTree = "<group>"; };
CF19532D1E5C062B00B14FF0 /* TaggedViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TaggedViewManager.m; path = ZulipMobile/TaggedViewManager.m; sourceTree = "<group>"; };
D5664A74FA8048439CBAB734 /* libRNDeviceInfo.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNDeviceInfo.a; sourceTree = "<group>"; };
F56CBB1B9A6449F895C858C6 /* Entypo.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Entypo.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Entypo.ttf"; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -386,6 +401,16 @@
13B07FB61A68108700A75B9A /* Info.plist */,
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
13B07FB71A68108700A75B9A /* main.m */,
CF1953221E5BE66800B14FF0 /* AnchorScrollView.h */,
CF1953231E5BE67D00B14FF0 /* AnchorScrollView.m */,
CF15A6B31E5C21CB003EA77F /* AnchorScrollViewManager.h */,
CF1953251E5BF2E000B14FF0 /* AnchorScrollViewManager.m */,
CF1953291E5C05BF00B14FF0 /* UIView+Tag.h */,
CF15A6B11E5C0C8A003EA77F /* UIView+Tag.m */,
CF19532C1E5C062B00B14FF0 /* TaggedViewManager.h */,
CF19532D1E5C062B00B14FF0 /* TaggedViewManager.m */,
CF15A6B51E5C56E5003EA77F /* OptimizedGifDecoder.m */,
CF15A6B71E5C56F8003EA77F /* OptimizedGifDecoder.h */,
);
name = ZulipMobile;
sourceTree = "<group>";
Expand Down Expand Up @@ -878,8 +903,13 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CF1953261E5BF2E000B14FF0 /* AnchorScrollViewManager.m in Sources */,
CF19532E1E5C062B00B14FF0 /* TaggedViewManager.m in Sources */,
CF1953241E5BE67D00B14FF0 /* AnchorScrollView.m in Sources */,
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
CF15A6B61E5C56E5003EA77F /* OptimizedGifDecoder.m in Sources */,
13B07FC11A68108700A75B9A /* main.m in Sources */,
CF15A6B21E5C0C8A003EA77F /* UIView+Tag.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
12 changes: 12 additions & 0 deletions ios/ZulipMobile/AnchorScrollView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// AnchorScrollView.h
// ZulipMobile
//

#import <React/RCTScrollView.h>

@interface AnchorScrollView : RCTScrollView

@property (nonatomic, assign) BOOL autoScrollToBottom;

@end
205 changes: 205 additions & 0 deletions ios/ZulipMobile/AnchorScrollView.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
/**
* 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.
*/

/*
* Modified for ZulipMobile
*/

#import "AnchorScrollView.h"
#import "UIView+Tag.h"
#import "UIView+React.h"

@interface RCTScrollView()
- (void) reactBridgeDidFinishTransaction;
- (void) dockClosestSectionHeader;
- (CGPoint)calculateOffsetForContentSize:(CGSize)newContentSize;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
- (void)sendScrollEventWithName:(NSString *)eventName
scrollView:(UIScrollView *)scrollView
userData:(NSDictionary *)userData;
- (NSArray *)calculateChildFramesData;
@end

@implementation AnchorScrollView
{
__weak NSString *_anchorTag;
CGPoint _lastAnchorPoint;
CGPoint _lastContentOffset;
}

#define RCT_SEND_SCROLL_EVENT(_eventName, _userData) { \
NSString *eventName = NSStringFromSelector(@selector(_eventName)); \
[super sendScrollEventWithName:eventName scrollView:super.scrollView userData:_userData]; \
}

#define RCT_FORWARD_SCROLL_EVENT(call) \
NSHashTable *scrollListeners = [super valueForKey:@"_scrollListeners"]; \
for (NSObject<UIScrollViewDelegate> *scrollViewListener in scrollListeners) { \
if ([scrollViewListener respondsToSelector:_cmd]) { \
[scrollViewListener call]; \
} \
}

- (void) reactBridgeDidFinishTransaction
{
[super reactBridgeDidFinishTransaction];
[super.scrollView performSelector:@selector(dockClosestSectionHeader)];
[self findAnchor:false];
}

- (CGFloat) anchorChange
{
UIView *contentView = [self contentView];
if (_anchorTag) {
__block UIView *anchorView = nil;
[[contentView reactSubviews] enumerateObjectsUsingBlock:
^(UIView *anchor, __unused NSUInteger idx, BOOL *stop) {
NSString *tagID = [anchor tagID];
if (tagID && [tagID isEqualToString:_anchorTag]) {
anchorView = anchor;
*stop = YES;
return;
}
}];
if (anchorView) {
return anchorView.frame.origin.y - _lastAnchorPoint.y;
}
}
return CGFLOAT_MAX;
}

- (void) findAnchor:(BOOL)scrollingDown
{
UIView *contentView = [self contentView];
CGFloat scrollTop = self.scrollView.bounds.origin.y + self.scrollView.contentInset.top;
CGFloat scrollBottom = self.scrollView.bounds.origin.y + self.scrollView.contentInset.top + self.scrollView.bounds.size.height;

__block UIView *nextAnchor = nil;
_anchorTag = nil;

NSEnumerationOptions opts = scrollingDown ? NSEnumerationReverse : 0;
[[contentView reactSubviews] enumerateObjectsWithOptions:opts usingBlock:
^(UIView *anchor, __unused NSUInteger idx, BOOL *stop) {
if (![anchor tagID]) {
return;
}
CGFloat height = anchor.bounds.size.height;
CGFloat top = anchor.center.y - height * anchor.layer.anchorPoint.y;
CGFloat bottom = anchor.center.y + height * anchor.layer.anchorPoint.y;

if (!nextAnchor) {
BOOL condition = scrollingDown ? top <= scrollBottom : bottom >= scrollTop;

// Find the next anchor
if (condition) {
nextAnchor = anchor;
_lastAnchorPoint = nextAnchor.frame.origin;
_anchorTag = [anchor tagID];
*stop = YES;
return;
}
}
}];
}

- (NSArray *) calculateVisibleViews
{
NSMutableArray *visibleIds = [NSMutableArray new];
CGFloat scrollTop = self.scrollView.bounds.origin.y + self.scrollView.contentInset.top;
CGFloat scrollBottom = self.scrollView.bounds.origin.y + self.scrollView.contentInset.top + self.scrollView.bounds.size.height;

[[self.contentView reactSubviews] enumerateObjectsUsingBlock:
^(UIView *anchor, __unused NSUInteger idx, __unused BOOL *stop) {
NSString *tagID = [anchor tagID];
if (!tagID) {
return;
}
CGFloat height = anchor.bounds.size.height;
CGFloat top = anchor.center.y - height * anchor.layer.anchorPoint.y;
CGFloat bottom = anchor.center.y + height * anchor.layer.anchorPoint.y;
if (bottom >= scrollTop && top <= scrollBottom) {
[visibleIds addObject:tagID];
}
}];
return visibleIds;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
BOOL allowNextScrollNoMatterWhat = [[super valueForKey:@"_allowNextScrollNoMatterWhat"] boolValue];
NSTimeInterval lastScrollDispatchTime = [[super valueForKey:@"_lastScrollDispatchTime"] doubleValue];


[super.scrollView performSelector:@selector(dockClosestSectionHeader)];
[super updateClippedSubviews];

NSTimeInterval now = CACurrentMediaTime();

BOOL scrollingDown = _lastContentOffset.y <= super.scrollView.contentOffset.y;
[self findAnchor:scrollingDown];
_lastContentOffset = self.scrollView.contentOffset;

/**
* TODO: this logic looks wrong, and it may be because it is. Currently, if _scrollEventThrottle
* is set to zero (the default), the "didScroll" event is only sent once per scroll, instead of repeatedly
* while scrolling as expected. However, if you "fix" that bug, ScrollView will generate repeated
* warnings, and behave strangely (ListView works fine however), so don't fix it unless you fix that too!
*/
if (allowNextScrollNoMatterWhat ||
(super.scrollEventThrottle > 0 && super.scrollEventThrottle < (now - lastScrollDispatchTime))) {

// Calculate changed frames
NSArray<NSDictionary *> *childFrames = [super calculateChildFramesData];
NSArray *visibleIds = [self calculateVisibleViews];

// Dispatch event
RCT_SEND_SCROLL_EVENT(onScroll, (@{
@"updatedChildFrames": childFrames,
@"visibleIds": visibleIds
}));

// Update dispatch time
[super setValue:[NSNumber numberWithDouble:now] forKey:@"_lastScrollDispatchTime"];
[super setValue:[NSNumber numberWithBool:NO] forKey:@"_allowNextScrollNoMatterWhat"];
}
RCT_FORWARD_SCROLL_EVENT(scrollViewDidScroll:scrollView);
}

- (CGPoint)calculateOffsetForContentSize:(CGSize)newContentSize
{
CGPoint oldOffset = self.scrollView.contentOffset;
CGPoint newOffset = [super calculateOffsetForContentSize:newContentSize];

CGSize oldContentSize = self.scrollView.contentSize;

// Adjust the offset based on the anchor
CGFloat offsetHeight = oldOffset.y + self.bounds.size.height;
CGFloat anchorChange = [self anchorChange];
if (anchorChange != CGFLOAT_MAX) {
if (self.autoScrollToBottom &&
oldContentSize.height >= self.bounds.size.height &&
offsetHeight >= oldContentSize.height) {
newOffset.y = MAX(0, newContentSize.height - self.bounds.size.height);
} else {
newOffset.y = MAX(0, oldOffset.y + anchorChange);
}
} else {
// offset falls outside of bounds, scroll back to end of list
newOffset.y = MAX(0, newContentSize.height - self.bounds.size.height);
}
return newOffset;
}

- (void)didSetProps:(NSArray<NSString *> *)changedProps
{
// Do nothing
// This fixes a bug with section headers in RCTScrollView
}

@end
10 changes: 10 additions & 0 deletions ios/ZulipMobile/AnchorScrollViewManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// AnchorScrollViewManager.h
// ZulipMobile
//

#import <React/RCTScrollViewManager.h>

@interface AnchorScrollViewManager : RCTScrollViewManager

@end
58 changes: 58 additions & 0 deletions ios/ZulipMobile/AnchorScrollViewManager.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* 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.
*/

/*
* Modified for ZulipMobile
*/

#import "AnchorScrollViewManager.h"

#import "AnchorScrollView.h"
#import "RCTBridgeModule.h"

#import <objc/runtime.h>

@implementation AnchorScrollViewManager

RCT_EXTERN void RCTRegisterModule(Class);

+ (NSString *) moduleName {
return @"AnchorScrollView";
}

+ (void)load {
// This is pure voodoo
// It copies over all of the RCTScrollViewManager properties onto this class
unsigned int count = 0;
Method *methods = class_copyMethodList(object_getClass([self superclass]), &count);
for (unsigned int i = 0; i < count; i++) {
SEL selector = method_getName(methods[i]);
const char *selectorName = sel_getName(selector);
if (strncmp(selectorName, "propConfig", strlen("propConfig")) != 0) {
continue;
}
class_addMethod(
object_getClass([self class]),
method_getName(methods[i]),
method_getImplementation(methods[i]),
method_getTypeEncoding(methods[i])
);
}

RCTRegisterModule(self);
}

- (UIView *)view
{
return [[AnchorScrollView alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
}

RCT_EXPORT_VIEW_PROPERTY(autoScrollToBottom, BOOL)

@end
18 changes: 18 additions & 0 deletions ios/ZulipMobile/OptimizedGifDecoder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* 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.
*/

/*
* Modified from RCTGIFImageDecoder.h for ZulipMobile
*/

#import <React/RCTImageLoader.h>

@interface OptimizedGifDecoder : NSObject <RCTImageDataDecoder>

@end
Loading

0 comments on commit 4b95b12

Please sign in to comment.