Skip to content

Commit

Permalink
Initial support for null as color (#5393)
Browse files Browse the repository at this point in the history
This commit adds initial support for passing null as a valid value for color properties.
When a color property is applied, if it wasn't specified then the default color is applied. Now, when null is passed, no color will be applied
leaving the last color applied as is.

This is useful when showing an Overlay and you'd like to keep the current StatusBar color unaffected. Another usecase would be when you'd like to avoid coloring an icon in BottomTabs.
  • Loading branch information
guyca authored Aug 20, 2019
1 parent 8663669 commit 3519837
Show file tree
Hide file tree
Showing 40 changed files with 305 additions and 126 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.reactnativenavigation.parse.params;

import android.graphics.Color;

import javax.annotation.Nonnull;

public class DontApplyColour extends Colour {
public DontApplyColour() {
super(Color.TRANSPARENT);
}

@Override
public boolean hasValue() {
return true;
}

@Override
public boolean canApplyValue() {
return false;
}

@Nonnull
@Override
public String toString() {
return "NoColor";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ public boolean hasValue() {
return value != null;
}

public boolean canApplyValue() {
return true;
}

public boolean equals(Param other) {
return value == other.value || equalsNotNull(value, other.value);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.reactnativenavigation.parse.parsers;

import com.reactnativenavigation.parse.params.Colour;
import com.reactnativenavigation.parse.params.DontApplyColour;
import com.reactnativenavigation.parse.params.NullColor;

import org.json.JSONObject;

public class ColorParser {
public static Colour parse(JSONObject json, String color) {
return json.has(color) ? new Colour(json.optInt(color)) : new NullColor();
if (json.has(color)) {
return json.opt(color) instanceof Integer ? new Colour(json.optInt(color)) : new DontApplyColour();
}
return new NullColor();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ public void applyOptions() {
for (int i = 0; i < tabs.size(); i++) {
BottomTabOptions tab = tabs.get(i).resolveCurrentOptions(defaultOptions).bottomTabOptions;
bottomTabs.setTitleTypeface(i, tab.fontFamily);
bottomTabs.setIconActiveColor(i, tab.selectedIconColor.get(null));
bottomTabs.setIconInactiveColor(i, tab.iconColor.get(null));
if (tab.selectedIconColor.canApplyValue()) bottomTabs.setIconActiveColor(i, tab.selectedIconColor.get(null));
if (tab.iconColor.canApplyValue()) bottomTabs.setIconInactiveColor(i, tab.iconColor.get(null));
bottomTabs.setTitleActiveColor(i, tab.selectedTextColor.get(null));
bottomTabs.setTitleInactiveColor(i, tab.textColor.get(null));
bottomTabs.setTitleInactiveTextSizeInSp(i, tab.fontSize.hasValue() ? Float.valueOf(tab.fontSize.get()) : null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ private void setStatusBarVisible(Bool visible) {
}

private void setStatusBarBackgroundColor(StatusBarOptions statusBar) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && statusBar.backgroundColor.canApplyValue()) {
int defaultColor = statusBar.visible.isTrueOrUndefined() ? Color.BLACK : Color.TRANSPARENT;
activity.getWindow().setStatusBarColor(statusBar.backgroundColor.get(defaultColor));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.reactnativenavigation.parse.parsers;

import com.reactnativenavigation.BaseTest;
import com.reactnativenavigation.parse.params.DontApplyColour;

import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;

import static org.assertj.core.api.Java6Assertions.assertThat;

public class ColorParseTest extends BaseTest {

@Test
public void nullIsParsedAsNoColor() throws JSONException {
JSONObject json = new JSONObject();
json.put("color", "NoColor");
assertThat(ColorParser.parse(json, "color")).isInstanceOf(DontApplyColour.class);
}
}
17 changes: 17 additions & 0 deletions lib/ios/Color.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,21 @@ - (UIColor *)getWithDefaultValue:(id)defaultValue {
return [super getWithDefaultValue:defaultValue];
}

-(NSString *)description {
return [self hexStringFromColor:[self getWithDefaultValue:nil]];
}

- (NSString *)hexStringFromColor:(UIColor *)color {
const CGFloat *components = CGColorGetComponents(color.CGColor);

CGFloat r = components[0];
CGFloat g = components[1];
CGFloat b = components[2];

return [NSString stringWithFormat:@"#%02lX%02lX%02lX",
lroundf(r * 255),
lroundf(g * 255),
lroundf(b * 255)];
}

@end
6 changes: 5 additions & 1 deletion lib/ios/ColorParser.m
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
#import "ColorParser.h"
#import "NullColor.h"
#import "NoColor.h"
#import <React/RCTConvert.h>

@implementation ColorParser

+ (Color *)parse:(NSDictionary *)json key:(NSString *)key {
return json[key] ? [[Color alloc] initWithValue:[RCTConvert UIColor:json[key]]] : [NullColor new];
if (json[key]) {
return [json[key] isKindOfClass:[NSNumber class]] ? [[Color alloc] initWithValue:[RCTConvert UIColor:json[key]]] : [NoColor new];
}
return [NullColor new];
}

@end
5 changes: 5 additions & 0 deletions lib/ios/NoColor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#import "Color.h"

@interface NoColor : Color

@end
22 changes: 22 additions & 0 deletions lib/ios/NoColor.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#import "NoColor.h"
#import "Color.h"


@implementation NoColor

- (BOOL)hasValue {
return YES;
}

- (UIColor *)get {
// return nil;
return UIColor.cyanColor;
}

- (UIColor *)getWithDefaultValue:(id)defaultValue {
return UIColor.cyanColor;
// return nil;
}


@end
4 changes: 3 additions & 1 deletion lib/ios/RNNBasePresenter.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ typedef void (^RNNReactViewReadyCompletionBlock)(void);

@property(nonatomic, strong) NSString *boundComponentId;

- (instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions;

- (void)bindViewController:(UIViewController *)boundViewController;

- (void)applyOptionsOnInit:(RNNNavigationOptions *)initialOptions;
Expand All @@ -20,7 +22,7 @@ typedef void (^RNNReactViewReadyCompletionBlock)(void);

- (void)applyDotIndicator:(UIViewController *)child;

- (void)mergeOptions:(RNNNavigationOptions *)newOptions currentOptions:(RNNNavigationOptions *)currentOptions defaultOptions:(RNNNavigationOptions *)defaultOptions;
- (void)mergeOptions:(RNNNavigationOptions *)newOptions currentOptions:(RNNNavigationOptions *)currentOptions;

- (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock;

Expand Down
67 changes: 35 additions & 32 deletions lib/ios/RNNBasePresenter.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@

@interface RNNBasePresenter ()
@property(nonatomic, strong) RNNDotIndicatorPresenter* dotIndicatorPresenter;
@property(nonatomic, strong) RNNNavigationOptions* defaultOptions;
@end

@implementation RNNBasePresenter

-(instancetype)init {
-(instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions {
self = [super init];
self.dotIndicatorPresenter = [RNNDotIndicatorPresenter new];
_defaultOptions = defaultOptions;
self.dotIndicatorPresenter = [[RNNDotIndicatorPresenter alloc] initWithDefaultOptions:_defaultOptions];
return self;
}

Expand All @@ -33,64 +34,66 @@ - (void)applyOptionsOnViewDidLayoutSubviews:(RNNNavigationOptions *)options {

- (void)applyOptionsOnWillMoveToParentViewController:(RNNNavigationOptions *)options {
UIViewController *viewController = self.boundViewController;
RNNNavigationOptions * withDefault = [options withDefault:_defaultOptions];

if (options.bottomTab.text.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:options.bottomTab];
if (withDefault.bottomTab.text.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (options.bottomTab.icon.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:options.bottomTab];
if (withDefault.bottomTab.icon.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (options.bottomTab.selectedIcon.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:options.bottomTab];
if (withDefault.bottomTab.selectedIcon.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (options.bottomTab.badgeColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:options.bottomTab];
if (withDefault.bottomTab.badgeColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (options.bottomTab.textColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:options.bottomTab];
if (withDefault.bottomTab.textColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (options.bottomTab.iconColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:options.bottomTab];
if (withDefault.bottomTab.iconColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (options.bottomTab.selectedTextColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:options.bottomTab];
if (withDefault.bottomTab.selectedTextColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}

if (options.bottomTab.selectedIconColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:options.bottomTab];
if (withDefault.bottomTab.selectedIconColor.hasValue) {
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:withDefault.bottomTab];
viewController.tabBarItem = tabItem;
}
}

- (void)applyOptions:(RNNNavigationOptions *)options {
UIViewController *viewController = self.boundViewController;
RNNNavigationOptions * withDefault = [options withDefault:_defaultOptions];

if (options.bottomTab.badge.hasValue && [viewController.parentViewController isKindOfClass:[UITabBarController class]]) {
[viewController rnn_setTabBarItemBadge:options.bottomTab];
if (withDefault.bottomTab.badge.hasValue && [viewController.parentViewController isKindOfClass:[UITabBarController class]]) {
[viewController rnn_setTabBarItemBadge:withDefault.bottomTab.badge.get];
}

if (options.bottomTab.badgeColor.hasValue && [viewController.parentViewController isKindOfClass:[UITabBarController class]]) {
[viewController rnn_setTabBarItemBadgeColor:options.bottomTab.badgeColor.get];
if (withDefault.bottomTab.badgeColor.hasValue && [viewController.parentViewController isKindOfClass:[UITabBarController class]]) {
[viewController rnn_setTabBarItemBadgeColor:withDefault.bottomTab.badgeColor.get];
}
}

- (void)mergeOptions:(RNNNavigationOptions *)newOptions currentOptions:(RNNNavigationOptions *)currentOptions defaultOptions:(RNNNavigationOptions *)defaultOptions {
- (void)mergeOptions:(RNNNavigationOptions *)newOptions currentOptions:(RNNNavigationOptions *)currentOptions {
UIViewController *viewController = self.boundViewController;
if (newOptions.bottomTab.badge.hasValue && [viewController.parentViewController isKindOfClass:[UITabBarController class]]) {
[viewController rnn_setTabBarItemBadge:newOptions.bottomTab];
[viewController rnn_setTabBarItemBadge:newOptions.bottomTab.badge.get];
}

if (newOptions.bottomTab.badgeColor.hasValue && [viewController.parentViewController isKindOfClass:[UITabBarController class]]) {
Expand All @@ -102,43 +105,43 @@ - (void)mergeOptions:(RNNNavigationOptions *)newOptions currentOptions:(RNNNavig
}

if (newOptions.bottomTab.text.hasValue) {
RNNNavigationOptions *buttonsResolvedOptions = [(RNNNavigationOptions *) [currentOptions overrideOptions:newOptions] withDefault:defaultOptions];
RNNNavigationOptions *buttonsResolvedOptions = (RNNNavigationOptions *) [currentOptions overrideOptions:newOptions];
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:buttonsResolvedOptions.bottomTab];
viewController.tabBarItem = tabItem;
}

if (newOptions.bottomTab.icon.hasValue) {
RNNNavigationOptions *buttonsResolvedOptions = [(RNNNavigationOptions *) [currentOptions overrideOptions:newOptions] withDefault:defaultOptions];
RNNNavigationOptions *buttonsResolvedOptions = (RNNNavigationOptions *) [currentOptions overrideOptions:newOptions];
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:buttonsResolvedOptions.bottomTab];
viewController.tabBarItem = tabItem;
}

if (newOptions.bottomTab.selectedIcon.hasValue) {
RNNNavigationOptions *buttonsResolvedOptions = [(RNNNavigationOptions *) [currentOptions overrideOptions:newOptions] withDefault:defaultOptions];
RNNNavigationOptions *buttonsResolvedOptions = (RNNNavigationOptions *) [currentOptions overrideOptions:newOptions];
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:buttonsResolvedOptions.bottomTab];
viewController.tabBarItem = tabItem;
}

if (newOptions.bottomTab.textColor.hasValue) {
RNNNavigationOptions *buttonsResolvedOptions = [(RNNNavigationOptions *) [currentOptions overrideOptions:newOptions] withDefault:defaultOptions];
RNNNavigationOptions *buttonsResolvedOptions = (RNNNavigationOptions *) [currentOptions overrideOptions:newOptions];
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:buttonsResolvedOptions.bottomTab];
viewController.tabBarItem = tabItem;
}

if (newOptions.bottomTab.selectedTextColor.hasValue) {
RNNNavigationOptions *buttonsResolvedOptions = [(RNNNavigationOptions *) [currentOptions overrideOptions:newOptions] withDefault:defaultOptions];
RNNNavigationOptions *buttonsResolvedOptions = (RNNNavigationOptions *) [currentOptions overrideOptions:newOptions];
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:buttonsResolvedOptions.bottomTab];
viewController.tabBarItem = tabItem;
}

if (newOptions.bottomTab.iconColor.hasValue) {
RNNNavigationOptions *buttonsResolvedOptions = [(RNNNavigationOptions *) [currentOptions overrideOptions:newOptions] withDefault:defaultOptions];
RNNNavigationOptions *buttonsResolvedOptions = (RNNNavigationOptions *) [currentOptions overrideOptions:newOptions];
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:buttonsResolvedOptions.bottomTab];
viewController.tabBarItem = tabItem;
}

if (newOptions.bottomTab.selectedIconColor.hasValue) {
RNNNavigationOptions *buttonsResolvedOptions = [(RNNNavigationOptions *) [currentOptions overrideOptions:newOptions] withDefault:defaultOptions];
RNNNavigationOptions *buttonsResolvedOptions = (RNNNavigationOptions *) [currentOptions overrideOptions:newOptions];
UITabBarItem *tabItem = [RNNTabBarItemCreator updateTabBarItem:viewController.tabBarItem bottomTabOptions:buttonsResolvedOptions.bottomTab];
viewController.tabBarItem = tabItem;
}
Expand Down
Loading

0 comments on commit 3519837

Please sign in to comment.