Skip to content

Commit

Permalink
iOS: Support <ActivityIndicator> component
Browse files Browse the repository at this point in the history
Summary: Setup for using <ActivityIndicator> component in Fabric.

Reviewed By: shergin

Differential Revision: D8107528

fbshipit-source-id: e3ba46d1538f5d5a2fa6f75639caaaa51156c452
  • Loading branch information
fkgozali authored and facebook-github-bot committed May 23, 2018
1 parent 7014a30 commit 8bfe78c
Show file tree
Hide file tree
Showing 14 changed files with 382 additions and 8 deletions.
5 changes: 4 additions & 1 deletion RNTester/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ PODS:
- React/Core
- React/RCTWebSocket
- React/fabric (1000.0.0):
- React/fabric/activityindicator (= 1000.0.0)
- React/fabric/attributedstring (= 1000.0.0)
- React/fabric/core (= 1000.0.0)
- React/fabric/debug (= 1000.0.0)
Expand All @@ -32,6 +33,8 @@ PODS:
- React/fabric/textlayoutmanager (= 1000.0.0)
- React/fabric/uimanager (= 1000.0.0)
- React/fabric/view (= 1000.0.0)
- React/fabric/activityindicator (1000.0.0):
- Folly (= 2016.10.31.00)
- React/fabric/attributedstring (1000.0.0):
- Folly (= 2016.10.31.00)
- React/fabric/core (1000.0.0):
Expand Down Expand Up @@ -141,7 +144,7 @@ SPEC CHECKSUMS:
DoubleConversion: a9706f16e388b53ff12cca34473428ee29746a26
Folly: c89ac2d5c6ab169cd7397ef27485c44f35f742c7
glog: 3931855c9cc99c3fab1355fc162fe369162d8183
React: 81df86644d0bca489723c964b33b005901ebfb3b
React: 1fe0eb13d90b625d94c3b117c274dcfd2e760e11
yoga: b1ce48b6cf950b98deae82838f5173ea7cf89e85

PODFILE CHECKSUM: 30aa63dcdbb3546a2bacdfd4e005bcca50c9b55c
Expand Down
9 changes: 9 additions & 0 deletions React.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,15 @@ Pod::Spec.new do |s|
end

s.subspec "fabric" do |ss|
ss.subspec "activityindicator" do |sss|
sss.dependency "Folly", folly_version
sss.compiler_flags = folly_compiler_flags
sss.source_files = "ReactCommon/fabric/activityindicator/**/*.{cpp,h}"
sss.exclude_files = "**/tests/*"
sss.header_dir = "fabric/activityindicator"
sss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_ROOT)/Folly\"" }
end

ss.subspec "attributedstring" do |sss|
sss.dependency "Folly", folly_version
sss.compiler_flags = folly_compiler_flags
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* 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 <UIKit/UIKit.h>

#import <React/RCTViewComponentView.h>

NS_ASSUME_NONNULL_BEGIN

/**
* UIView class for root <ShimmeringView> component.
*/
@interface RCTActivityIndicatorViewComponentView : RCTViewComponentView

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* 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 "RCTActivityIndicatorViewComponentView.h"

#import <fabric/activityindicator/ActivityIndicatorViewProps.h>

using namespace facebook::react;

static UIActivityIndicatorViewStyle convertActivityIndicatorViewStyle(const ActivityIndicatorViewSize &size) {
switch (size) {
case ActivityIndicatorViewSize::Small:
return UIActivityIndicatorViewStyleWhite;
case ActivityIndicatorViewSize::Large:
return UIActivityIndicatorViewStyleWhiteLarge;
}
}

@implementation RCTActivityIndicatorViewComponentView {
UIActivityIndicatorView *_activityIndicatorView;
}

- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
_activityIndicatorView = [[UIActivityIndicatorView alloc] initWithFrame:self.bounds];
_activityIndicatorView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

auto &&defaultProps = ActivityIndicatorViewProps();

if (defaultProps.animating) {
[_activityIndicatorView startAnimating];
} else {
[_activityIndicatorView stopAnimating];
}
_activityIndicatorView.color = [UIColor colorWithCGColor:defaultProps.color.get()];
_activityIndicatorView.hidesWhenStopped = defaultProps.hidesWhenStopped;
_activityIndicatorView.activityIndicatorViewStyle = convertActivityIndicatorViewStyle(defaultProps.size);

[self addSubview:_activityIndicatorView];
}

return self;
}

- (void)updateProps:(SharedProps)props oldProps:(SharedProps)oldProps
{
if (!oldProps) {
oldProps = _props ?: std::make_shared<ActivityIndicatorViewProps>();
}
_props = props;

[super updateProps:props oldProps:oldProps];

auto oldViewProps = *std::dynamic_pointer_cast<const ActivityIndicatorViewProps>(oldProps);
auto newViewProps = *std::dynamic_pointer_cast<const ActivityIndicatorViewProps>(props);

if (oldViewProps.animating != newViewProps.animating) {
if (newViewProps.animating) {
[_activityIndicatorView startAnimating];
} else {
[_activityIndicatorView stopAnimating];
}
}

if (oldViewProps.color.get() != newViewProps.color.get()) {
_activityIndicatorView.color = [UIColor colorWithCGColor:newViewProps.color.get()];
}

// TODO: This prop should be deprecated.
if (oldViewProps.hidesWhenStopped != newViewProps.hidesWhenStopped) {
_activityIndicatorView.hidesWhenStopped = newViewProps.hidesWhenStopped;
}

if (oldViewProps.size != newViewProps.size) {
_activityIndicatorView.activityIndicatorViewStyle = convertActivityIndicatorViewStyle(newViewProps.size);
}
}

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* 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.
*/

#pragma once

#include <fabric/activityindicator/ActivityIndicatorViewShadowNode.h>
#include <fabric/core/ConcreteComponentDescriptor.h>

namespace facebook {
namespace react {

using ActivityIndicatorViewComponentDescriptor = ConcreteComponentDescriptor<ActivityIndicatorViewShadowNode>;

} // namespace react
} // namespace facebook
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* 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.
*/

#include <fabric/activityindicator/ActivityIndicatorViewProps.h>
#include <fabric/activityindicator/conversions.h>
#include <fabric/core/propsConversions.h>

namespace facebook {
namespace react {

ActivityIndicatorViewProps::ActivityIndicatorViewProps(const ActivityIndicatorViewProps &sourceProps, const RawProps &rawProps):
ViewProps(sourceProps, rawProps),
animating(convertRawProp(rawProps, "animating", sourceProps.animating)),
color(convertRawProp(rawProps, "color", sourceProps.color)),
hidesWhenStopped(convertRawProp(rawProps, "hidesWhenStopped", sourceProps.hidesWhenStopped)),
size(convertRawProp(rawProps, "size", sourceProps.size)) {}

} // namespace react
} // namespace facebook
32 changes: 32 additions & 0 deletions ReactCommon/fabric/activityindicator/ActivityIndicatorViewProps.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* 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.
*/

#include <fabric/activityindicator/primitives.h>
#include <fabric/graphics/Color.h>
#include <fabric/view/ViewProps.h>

namespace facebook {
namespace react {

// TODO (T28334063): Consider for codegen.
class ActivityIndicatorViewProps final:
public ViewProps {

public:
ActivityIndicatorViewProps() = default;
ActivityIndicatorViewProps(const ActivityIndicatorViewProps &sourceProps, const RawProps &rawProps);

#pragma mark - Props

const bool animating {true};
const SharedColor color {colorFromComponents({153/255.0, 153/255.0, 153/255.0, 1.0})}; // #999999
const bool hidesWhenStopped {true};
const ActivityIndicatorViewSize size {ActivityIndicatorViewSize::Small};
};

} // namespace react
} // namespace facebook
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* 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.
*/

#include <fabric/activityindicator/ActivityIndicatorViewShadowNode.h>

namespace facebook {
namespace react {

ComponentName ActivityIndicatorViewShadowNode::getComponentName() const {
return ComponentName("ActivityIndicatorView");
}

} // namespace react
} // namespace facebook
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* 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.
*/

#pragma once

#include <fabric/activityindicator/ActivityIndicatorViewProps.h>
#include <fabric/view/ConcreteViewShadowNode.h>

namespace facebook {
namespace react {

/*
* `ShadowNode` for <ActivityIndicatorView> component.
*/
class ActivityIndicatorViewShadowNode final:
public ConcreteViewShadowNode<ActivityIndicatorViewProps> {

public:

using ConcreteViewShadowNode::ConcreteViewShadowNode;

ComponentName getComponentName() const override;
};

} // namespace react
} // namespace facebook
78 changes: 78 additions & 0 deletions ReactCommon/fabric/activityindicator/BUCK
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
load("//configurations/buck/apple:flag_defs.bzl", "OBJC_ARC_PREPROCESSOR_FLAGS", "get_application_ios_flags", "get_debug_preprocessor_flags")
load("//ReactNative:DEFS.bzl", "ANDROID", "APPLE", "IS_OSS_BUILD", "get_apple_inspector_flags", "react_native_xplat_target", "rn_xplat_cxx_library")

APPLE_COMPILER_FLAGS = []

if not IS_OSS_BUILD:
load("@xplat//configurations/buck/apple:flag_defs.bzl", "flags", "get_static_library_ios_flags")

APPLE_COMPILER_FLAGS = flags.get_flag_value(get_static_library_ios_flags(), "compiler_flags")

rn_xplat_cxx_library(
name = "activityindicator",
srcs = glob(
["**/*.cpp"],
exclude = glob(["tests/**/*.cpp"]),
),
headers = [],
header_namespace = "",
exported_headers = subdir_glob(
[
("", "*.h"),
],
prefix = "fabric/activityindicator",
),
compiler_flags = [
"-fexceptions",
"-frtti",
"-std=c++14",
"-Wall",
],
fbobjc_compiler_flags = APPLE_COMPILER_FLAGS,
fbobjc_preprocessor_flags = get_debug_preprocessor_flags() + get_apple_inspector_flags(),
fbobjc_tests = [
":tests",
],
macosx_tests_override = [],
platforms = (ANDROID, APPLE),
preprocessor_flags = [
"-DLOG_TAG=\"ReactNative\"",
"-DWITH_FBSYSTRACE=1",
],
tests = [],
visibility = ["PUBLIC"],
deps = [
"xplat//fbsystrace:fbsystrace",
"xplat//folly:headers_only",
"xplat//folly:memory",
"xplat//folly:molly",
"xplat//third-party/glog:glog",
"xplat//yoga:yoga",
react_native_xplat_target("fabric/debug:debug"),
react_native_xplat_target("fabric/core:core"),
react_native_xplat_target("fabric/graphics:graphics"),
react_native_xplat_target("fabric/view:view"),
],
)

if not IS_OSS_BUILD:
load("@xplat//build_defs:fb_xplat_cxx_test.bzl", "fb_xplat_cxx_test")

fb_xplat_cxx_test(
name = "tests",
srcs = glob(["tests/**/*.cpp"]),
headers = glob(["tests/**/*.h"]),
contacts = ["[email protected]"],
compiler_flags = [
"-fexceptions",
"-frtti",
"-std=c++14",
"-Wall",
],
platforms = APPLE,
deps = [
"xplat//folly:molly",
"xplat//third-party/gmock:gtest",
":activityindicator",
],
)
31 changes: 31 additions & 0 deletions ReactCommon/fabric/activityindicator/conversions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* 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.
*/

#pragma once

#include <fabric/activityindicator/primitives.h>
#include <folly/dynamic.h>

namespace facebook {
namespace react {

inline void fromDynamic(const folly::dynamic &value, ActivityIndicatorViewSize &result) {
auto string = value.asString();
if (string == "large") { result = ActivityIndicatorViewSize::Large; return; }
if (string == "small") { result = ActivityIndicatorViewSize::Small; return; }
abort();
}

inline std::string toString(const ActivityIndicatorViewSize &value) {
switch (value) {
case ActivityIndicatorViewSize::Large: return "large";
case ActivityIndicatorViewSize::Small: return "small";
}
}

} // namespace react
} // namespace facebook
Loading

0 comments on commit 8bfe78c

Please sign in to comment.