Jasonette/JASONETTE-iOS

View on GitHub
app/Jasonette/JasonButtonComponent.m

Summary

Maintainability
Test Coverage
//
//  JasonButtonComponent.m
//  Jasonette
//
//  Copyright © 2016 gliechtenstein. All rights reserved.
//
#import "JasonButtonComponent.h"
#import "NSData+ImageContentType.h"
#import "UIImage+GIF.h"

@implementation JasonButtonComponent
+ (UIView *)build: (UIButton *)component withJSON: (NSDictionary *)json withOptions: (NSDictionary *)options{
    if(!component){
        component = [[NoPaddingButton alloc] init];
    }
    NSMutableDictionary *mutable_json = [json mutableCopy];
    
    NSMutableDictionary *style;
    if(json[@"style"]){
        style = [json[@"style"] mutableCopy];
    }
    
    if(json[@"url"]){
        
        if(options && options[@"indexPath"]){
            NSString *url = (NSString *) [JasonHelper cleanNull:json[@"url"] type:@"string"];
            [[NSNotificationCenter defaultCenter] postNotificationName:@"setupIndexPathsForImage" object:nil userInfo:@{@"url": url, @"indexPath": options[@"indexPath"]}];
        }
        
        component.imageView.contentMode = UIViewContentModeScaleAspectFit;

        UIImage *placeholder_image = [UIImage imageNamed:@"placeholderr"];
        [component setImage:placeholder_image forState:UIControlStateNormal];
        NSString *url = (NSString *)[JasonHelper cleanNull: json[@"url"] type:@"string"];
        
        
        SDWebImageDownloader *manager = [SDWebImageManager sharedManager].imageDownloader;
        NSDictionary *session = [JasonHelper sessionForUrl:url];
        if(session && session.count > 0 && session[@"header"]){
            for(NSString *key in session[@"header"]){
                [manager setValue:session[@"header"][key] forHTTPHeaderField:key];
            }
        }
        if(json[@"header"] && [json[@"header"] count] > 0){
            for(NSString *key in json[@"header"]){
                [manager setValue:json[@"header"][key] forHTTPHeaderField:key];
            }
        }
        
        UIImageView * imageView = [[UIImageView alloc] init];
        
        if(![url containsString:@"{{"] && ![url containsString:@"}}"]){
            
            if([url containsString:@"file://"]){
                NSString *localImageName = [url substringFromIndex:7];
                UIImage *localImage;
                
                // Get data for local file
                NSString *filePath = [[NSBundle mainBundle] pathForResource:localImageName ofType:nil];
                NSData *data = [[NSFileManager defaultManager] contentsAtPath:filePath];
                
                // Check for animated GIF
                NSString *imageContentType = [NSData sd_contentTypeForImageData:data];
                if ([imageContentType isEqualToString:@"image/gif"]) {
                    localImage = [UIImage sd_animatedGIFWithData:data];
                } else {
                    localImage = [UIImage imageNamed:localImageName];
                }

                if(style[@"color"]){
                    // Setting tint color for an image
                    UIColor *newColor = [JasonHelper colorwithHexString:style[@"color"] alpha:1.0];
                    UIImage *newImage = [JasonHelper colorize:localImage into:newColor];
                    [component setImage:newImage forState:UIControlStateNormal];

                } else {
                    [component setImage:localImage forState:UIControlStateNormal];
                }
                                
                JasonComponentFactory.imageLoaded[url] = [NSValue valueWithCGSize:localImage.size];
            } else{
                [imageView sd_setImageWithURL:[NSURL URLWithString:url] placeholderImage:placeholder_image completed:^(UIImage *i, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                    if(!error){
                        JasonComponentFactory.imageLoaded[url] = [NSValue valueWithCGSize:i.size];
                        if(style[@"color"]){
                            NSString *colorHex = style[@"color"];
                            UIColor *c = [JasonHelper colorwithHexString:colorHex alpha:1.0];
                            UIImage *image = [imageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
                            [component setTintColor:c];
                            [component setImage: image forState:UIControlStateNormal];
                        } else {
                            [component setImage:imageView.image forState:UIControlStateNormal];
                        }
                    }
                }];
            }
        }
        [component setTitle:@"" forState:UIControlStateNormal];
        
        // Before applying common styles, Update the style attribute based on the fetched image dimension (different from other components)

        if(style){
            NSString *url = (NSString *)[JasonHelper cleanNull: json[@"url"] type:@"string"];
   
                    
            if(style[@"width"] && !style[@"height"]){
                // Width is set but height is not
                CGFloat aspectRatioMult;
                if(JasonComponentFactory.imageLoaded[url]){
                    @try{
                        CGSize size = [JasonComponentFactory.imageLoaded[url] CGSizeValue];
                        if(size.width > 0 && size.height > 0){
                            aspectRatioMult = (size.height / size.width);
                        } else {
                            aspectRatioMult = (imageView.image.size.height / imageView.image.size.width);
                        }
                    }
                    @catch (NSException *e){
                        aspectRatioMult = (imageView.image.size.height / imageView.image.size.width);
                    }
                } else {
                    aspectRatioMult = (imageView.image.size.height / imageView.image.size.width);
                }
                NSString *widthStr = style[@"width"];
                CGFloat width = [JasonHelper pixelsInDirection:@"horizontal" fromExpression:widthStr];
                style[@"height"] = [NSString stringWithFormat:@"%d", (int)(width * aspectRatioMult)];
            }
            if(style[@"height"] && !style[@"width"]){
                // Height is set but width is not
                CGFloat aspectRatioMult;
                if(JasonComponentFactory.imageLoaded[url]){
                    @try {
                        CGSize size = [JasonComponentFactory.imageLoaded[url] CGSizeValue];
                        if(size.width > 0 && size.height > 0){
                            aspectRatioMult = (size.width / size.height);
                        } else {
                            aspectRatioMult = (imageView.image.size.width / imageView.image.size.height);
                        }
                    }
                    @catch (NSException *e){
                        aspectRatioMult = (imageView.image.size.width / imageView.image.size.height);
                    }
                } else {
                    aspectRatioMult = (imageView.image.size.width / imageView.image.size.height);
                }
                NSString *heightStr = style[@"height"];
                CGFloat height = [JasonHelper pixelsInDirection:@"vertical" fromExpression:heightStr];
                style[@"width"] = [NSString stringWithFormat:@"%d", (int)(height * aspectRatioMult)];
            }
            mutable_json[@"style"] = style;
        }
        
    }
    else{
        [component setImage:nil forState:UIControlStateNormal];
        if(json[@"text"]){
            [component setTitle:[json[@"text"] description] forState:UIControlStateNormal];
        }

    }

    
    

    
    
    if(json[@"action"]){
        component.payload = [@{@"action": json[@"action"]} mutableCopy];
    }
    [component removeTarget:self.class action:@selector(actionButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
    [component addTarget:self.class action:@selector(actionButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
    
    
    // 1. Apply Common Style
    [self stylize:mutable_json component:component];


    // 2. Custom Style
    [component setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    if(style){
        if(json[@"text"]){
            // text button
            [self stylize:json text:component.titleLabel];
            
        }
        if(style[@"color"]){
            NSString *colorHex = style[@"color"];
            UIColor *c = [JasonHelper colorwithHexString:colorHex alpha:1.0];
            component.tintColor = c;
            [component setTitleColor:c forState:UIControlStateNormal];
        }

    }
    
    
    if(style){
        // Padding Override
        NSString *padding_left = @"0";
        NSString *padding_right = @"0";
        NSString *padding_top = @"0";
        NSString *padding_bottom = @"0";

        if(json[@"text"]){
            // padding 5 in case of text button
            padding_left = @"5";
            padding_right = @"5";
            padding_top = @"5";
            padding_bottom = @"5";
        }
        
        if(style[@"padding"]){
            NSString *padding = style[@"padding"];
            padding_left = padding;
            padding_top = padding;
            padding_right = padding;
            padding_bottom = padding;
        }
        
        if(style[@"padding_left"]) padding_left = style[@"padding_left"];
        if(style[@"padding_right"]) padding_right = style[@"padding_right"];
        if(style[@"padding_top"]) padding_top = style[@"padding_top"];
        if(style[@"padding_bottom"]) padding_bottom = style[@"padding_bottom"];
        component.contentEdgeInsets = UIEdgeInsetsMake([JasonHelper pixelsInDirection:@"vertical" fromExpression:padding_top], [JasonHelper pixelsInDirection:@"horizontal" fromExpression:padding_left], [JasonHelper pixelsInDirection:@"vertical" fromExpression:padding_bottom], [JasonHelper pixelsInDirection:@"horizontal" fromExpression:padding_right]);
        
        
        
        // align
        if(style[@"align"]){
            if([style[@"align"] isEqualToString:@"left"]){
                component.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
            } else if([style[@"align"] isEqualToString:@"right"]){
                component.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
            } else {
                if(json[@"url"]){
                    // image buttons fill horizontally
                    component.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
                } else {
                    // text buttons center horizontally
                    component.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;

                }
            }
        }
        component.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
        

    }
    
    [component setSelected:NO];
    return component;
}
+ (void)actionButtonClicked:(UIButton *)sender{
    if(sender.payload && sender.payload[@"action"]){
        [[Jason client] call: sender.payload[@"action"]];
    }
}

@end