Fixing favicon and feed title gradients in ios app.

This commit is contained in:
Samuel Clay 2015-09-16 20:24:11 -07:00
parent 29964b7b78
commit 16674eb8d0
7 changed files with 96 additions and 79 deletions

View file

@ -301,7 +301,7 @@ class MSocialProfile(mongo.Document):
for user_id in self.following_user_ids:
self.follow_user(user_id, force=force)
self.follow_user(self.user_id)
self.follow_user(self.user_id, force=force)
@property
def title(self):

View file

@ -342,7 +342,8 @@
- (NSDictionary *)getStory:(NSString *)storyHash;
+ (void)fillGradient:(CGRect)r startColor:(UIColor *)startColor endColor:(UIColor *)endColor;
+ (UIView *)makeGradientView:(CGRect)rect startColor:(NSString *)start endColor:(NSString *)end;
+ (UIColor *)faviconColor:(NSString *)colorString;
+ (UIView *)makeGradientView:(CGRect)rect startColor:(NSString *)start endColor:(NSString *)end borderColor:(NSString *)borderColor;
- (UIView *)makeFeedTitleGradient:(NSDictionary *)feed withRect:(CGRect)rect;
- (UIView *)makeFeedTitle:(NSDictionary *)feed;
- (void)saveFavicon:(UIImage *)image feedId:(NSString *)filename;

View file

@ -303,7 +303,7 @@
}
- (void)reachabilityChanged:(id)something {
NSLog(@"Reachability changed: %@", something);
// NSLog(@"Reachability changed: %@", something);
Reachability* reach = [Reachability reachabilityWithHostname:NEWSBLUR_HOST];
if (reach.isReachable && feedsViewController.isOffline) {
@ -2001,25 +2001,30 @@
UIGraphicsPopContext();
}
+ (UIView *)makeGradientView:(CGRect)rect startColor:(NSString *)start endColor:(NSString *)end {
+ (UIColor *)faviconColor:(NSString *)colorString {
if ([colorString class] == [NSNull class]) {
colorString = @"505050";
}
unsigned int color = 0;
NSScanner *scanner = [NSScanner scannerWithString:colorString];
[scanner scanHexInt:&color];
return UIColorFromRGB(color);
}
+ (UIView *)makeGradientView:(CGRect)rect startColor:(NSString *)start endColor:(NSString *)end borderColor:(NSString *)borderColor {
UIView *gradientView = [[UIView alloc] initWithFrame:rect];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = CGRectMake(0, 1, rect.size.width, rect.size.height-1);
gradient.opacity = 0.7;
unsigned int color = 0;
unsigned int colorFade = 0;
if ([start class] == [NSNull class]) {
start = @"505050";
}
if ([end class] == [NSNull class]) {
end = @"303030";
}
NSScanner *scanner = [NSScanner scannerWithString:start];
[scanner scanHexInt:&color];
NSScanner *scannerFade = [NSScanner scannerWithString:end];
[scannerFade scanHexInt:&colorFade];
gradient.colors = [NSArray arrayWithObjects:(id)[UIColorFromRGB(color) CGColor], (id)[UIColorFromRGB(colorFade) CGColor], nil];
gradient.colors = [NSArray arrayWithObjects:(id)[[self faviconColor:start] CGColor], (id)[[self faviconColor:end] CGColor], nil];
CALayer *whiteBackground = [CALayer layer];
whiteBackground.frame = CGRectMake(0, 1, rect.size.width, rect.size.height-1);
@ -2030,13 +2035,13 @@
CALayer *topBorder = [CALayer layer];
topBorder.frame = CGRectMake(0, 1, rect.size.width, 1);
topBorder.backgroundColor = [UIColorFromRGB(colorFade) colorWithAlphaComponent:0.7].CGColor;
topBorder.backgroundColor = [[self faviconColor:borderColor] colorWithAlphaComponent:0.7].CGColor;
topBorder.opacity = 1;
[gradientView.layer addSublayer:topBorder];
CALayer *bottomBorder = [CALayer layer];
bottomBorder.frame = CGRectMake(0, rect.size.height-1, rect.size.width, 1);
bottomBorder.backgroundColor = [UIColorFromRGB(colorFade) colorWithAlphaComponent:0.7].CGColor;
bottomBorder.backgroundColor = [[self faviconColor:borderColor] colorWithAlphaComponent:0.7].CGColor;
bottomBorder.opacity = 1;
[gradientView.layer addSublayer:bottomBorder];
@ -2053,8 +2058,9 @@
gradientView = [NewsBlurAppDelegate
makeGradientView:rect
startColor:[feed objectForKey:@"favicon_fade"]
endColor:[feed objectForKey:@"favicon_color"]];
endColor:[feed objectForKey:@"favicon_color"]
borderColor:[feed objectForKey:@"favicon_border"]];
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = [feed objectForKey:@"feed_title"];
titleLabel.backgroundColor = [UIColor clearColor];
@ -2064,14 +2070,15 @@
titleLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:11.0];
titleLabel.shadowOffset = CGSizeMake(0, 1);
if ([[feed objectForKey:@"favicon_text_color"] class] != [NSNull class]) {
titleLabel.textColor = [[feed objectForKey:@"favicon_text_color"]
isEqualToString:@"white"] ?
BOOL lightText = [[feed objectForKey:@"favicon_text_color"]
isEqualToString:@"white"];
UIColor *fadeColor = [NewsBlurAppDelegate faviconColor:[feed objectForKey:@"favicon_fade"]];
UIColor *borderColor = [NewsBlurAppDelegate faviconColor:[feed objectForKey:@"favicon_border"]];
titleLabel.textColor = lightText ?
[UIColor whiteColor] :
[UIColor blackColor];
titleLabel.shadowColor = [[feed objectForKey:@"favicon_text_color"]
isEqualToString:@"white"] ?
UIColorFromRGB(0x202020) :
UIColorFromRGB(0xd0d0d0);
titleLabel.shadowColor = lightText ? borderColor : fadeColor;
} else {
titleLabel.textColor = [UIColor whiteColor];
titleLabel.shadowColor = [UIColor blackColor];
@ -2090,8 +2097,9 @@
gradientView = [NewsBlurAppDelegate
makeGradientView:CGRectMake(0, -1, rect.size.width, 10)
// hard coding the 1024 as a hack for window.frame.size.width
startColor:[feed objectForKey:@"favicon_fade"]
endColor:[feed objectForKey:@"favicon_color"]];
startColor:[feed objectForKey:@"favicon_fade"]
endColor:[feed objectForKey:@"favicon_color"]
borderColor:[feed objectForKey:@"favicon_border"]];
}
gradientView.opaque = YES;

View file

@ -402,10 +402,6 @@
withRect:CGRectMake(0, -1, self.view.frame.size.width, 21)]; // 1024 hack for self.webView.frame.size.width
self.feedTitleGradient.tag = FEED_TITLE_GRADIENT_TAG; // Not attached yet. Remove old gradients, first.
[self.feedTitleGradient.layer setShadowColor:[[UIColor blackColor] CGColor]];
[self.feedTitleGradient.layer setShadowOffset:CGSizeMake(0, 0)];
[self.feedTitleGradient.layer setShadowOpacity:0];
[self.feedTitleGradient.layer setShadowRadius:12.0];
for (UIView *subview in self.webView.subviews) {
if (subview.tag == FEED_TITLE_GRADIENT_TAG) {
@ -628,18 +624,17 @@
}
- (NSString *)getComments {
NSString *comments = @"<div class=\"NB-feed-story-comments\">";
NSString *comments = @"";
if ([self.activeStory objectForKey:@"comment_count"] != [NSNull null] &&
[[self.activeStory objectForKey:@"comment_count"] intValue] > 0) {
if ([self.activeStory objectForKey:@"share_count"] != [NSNull null] &&
[[self.activeStory objectForKey:@"share_count"] intValue] > 0) {
NSDictionary *story = self.activeStory;
NSArray *friendsCommentsArray = [story objectForKey:@"friend_comments"];
NSArray *friendsShareArray = [story objectForKey:@"friend_shares"];
NSArray *publicCommentsArray = [story objectForKey:@"public_comments"];
if ([[story objectForKey:@"comment_count_friends"] intValue] > 0 ) {
comments = [comments stringByAppendingString:@"<div class=\"NB-story-comment-friend-comments\">"];
comments = [comments stringByAppendingString:@"<div class=\"NB-story-comments-group NB-story-comment-friend-comments\">"];
NSString *commentHeader = [NSString stringWithFormat:@
"<div class=\"NB-story-comments-friends-header-wrapper\">"
" <div class=\"NB-story-comments-friends-header\">%i comment%@</div>"
@ -649,16 +644,18 @@
comments = [comments stringByAppendingString:commentHeader];
// add friends comments
comments = [comments stringByAppendingFormat:@"<div class=\"NB-feed-story-comments\">"];
for (int i = 0; i < friendsCommentsArray.count; i++) {
NSString *comment = [self getComment:[friendsCommentsArray objectAtIndex:i]];
comments = [comments stringByAppendingString:comment];
}
comments = [comments stringByAppendingString:@"</div>"];
comments = [comments stringByAppendingString:@"</div>"];
}
NSInteger sharedByFriendsCount = [[story objectForKey:@"shared_by_friends"] count];
if (sharedByFriendsCount > 0 ) {
comments = [comments stringByAppendingString:@"<div class=\"NB-story-comment-friend-shares\">"];
comments = [comments stringByAppendingString:@"<div class=\"NB-story-comments-group NB-story-comment-friend-shares\">"];
NSString *commentHeader = [NSString stringWithFormat:@
"<div class=\"NB-story-comments-friend-shares-header-wrapper\">"
" <div class=\"NB-story-comments-friends-header\">%ld share%@</div>"
@ -667,17 +664,19 @@
sharedByFriendsCount == 1 ? @"" : @"s"];
comments = [comments stringByAppendingString:commentHeader];
// add friends comments
// add friend shares
comments = [comments stringByAppendingFormat:@"<div class=\"NB-feed-story-comments\">"];
for (int i = 0; i < friendsShareArray.count; i++) {
NSString *comment = [self getComment:[friendsShareArray objectAtIndex:i]];
comments = [comments stringByAppendingString:comment];
}
comments = [comments stringByAppendingString:@"</div>"];
comments = [comments stringByAppendingString:@"</div>"];
}
if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"show_public_comments"] boolValue] &&
[[story objectForKey:@"comment_count_public"] intValue] > 0 ) {
comments = [comments stringByAppendingString:@"<div class=\"NB-story-comment-public-comments\">"];
comments = [comments stringByAppendingString:@"<div class=\"NB-story-comments-group NB-story-comment-public-comments\">"];
NSString *publicCommentHeader = [NSString stringWithFormat:@
"<div class=\"NB-story-comments-public-header-wrapper\">"
" <div class=\"NB-story-comments-public-header\">%i public comment%@</div>"
@ -696,9 +695,6 @@
}
comments = [comments stringByAppendingString:@"</div>"];
}
comments = [comments stringByAppendingString:@"</div>"];
}
return comments;

View file

@ -594,8 +594,8 @@ del {
clear: both !important;
max-width: none !important;
}
.NB-feed-story-comments:last-child {
border-bottom: 1px solid #EAECE8;
.NB-story-comments-group:last-child {
border-bottom: 1px solid #EAECE8;
}
#story_pane .NB-story-comments-shares-teaser.NB-highlighted {
@ -879,29 +879,31 @@ a.NB-show-profile {
height: 36px;
width: 36px;
}
#story_pane .NB-story-comment-friend-shares .NB-story-comment .NB-user-avatar {
#story_pane .NB-story-comment-friend-shares .NB-user-avatar {
left: 12px;
top: 14px;
}
#story_pane .NB-story-comment-friend-shares .NB-story-comment .NB-user-avatar.NB-story-comment-reshare {
#story_pane .NB-story-comment-friend-shares .NB-user-avatar.NB-story-comment-reshare {
left: 18px;
top: 10px;
}
#story_pane .NB-story-comment-friend-shares .NB-story-comment .NB-user-avatar img {
#story_pane .NB-story-comment-friend-shares .NB-user-avatar img,
#story_pane .NB-story-comment-friend-shares .NB-user-avatar.NB-story-comment-reshare img {
height: 24px;
width: 24px;
margin-left: 6px;
}
#story_pane .NB-story-comment-friend-shares .NB-story-comment .NB-story-share-profile .NB-user-avatar img {
#story_pane .NB-story-comment-friend-shares .NB-story-share-profile .NB-user-avatar img {
margin-left: 0;
}
#story_pane .NB-story-comment-friend-shares .NB-story-comment .NB-user-avatar.NB-story-comment-reshare img {
#story_pane .NB-story-comment-friend-shares .NB-user-avatar.NB-story-comment-reshare img {
margin-left: 0;
margin-top: 12px;
}
#story_pane .NB-story-comment .NB-story-comment-author-container {
padding: 8px 0 0;
}
#story_pane .NB-story-comment-friend-shares .NB-story-comment .NB-story-comment-author-container {
#story_pane .NB-story-comment-friend-shares .NB-story-comment-author-container {
padding-top: 10px;
}
#story_pane .NB-story-comment .NB-story-comment-reshares {
@ -972,7 +974,7 @@ a.NB-show-profile {
margin: 3px 0 6px;
line-height: 12px;
}
#story_pane .NB-story-comment-friend-shares .NB-story-comment .NB-story-comment-location {
#story_pane .NB-story-comment-friend-shares .NB-story-comment-location {
margin-top: 0;
}
#story_pane .NB-story-comment .NB-button-wrapper {
@ -1047,7 +1049,6 @@ a.NB-show-profile {
#story_pane .NB-story-comments-friends-header-wrapper,
#story_pane .NB-story-comments-friend-shares-header-wrapper {
clear: both;
padding: 1px 0;
}
#story_pane .NB-story-comments-shares-teaser-wrapper {
border-top: 0;
@ -1063,7 +1064,6 @@ a.NB-show-profile {
font-weight: bold;
text-transform: uppercase;
font-size: 10px;
padding: 2px 12px;
overflow: hidden;
background-image: -webkit-gradient(linear, left top, left bottom, from(#F5F6F2), to(#E5E6E0));
padding: 6px 12px 6px;

View file

@ -36,29 +36,21 @@ NEWSBLUR.utils = {
return '0 1px 0 #222';
}
var r = parseInt(color.substr(0, 2), 16);
var g = parseInt(color.substr(2, 2), 16);
var b = parseInt(color.substr(4, 2), 16);
var r, g, b;
if (feed.is_light()) {
return [
'0 1px 0 ',
'rgb(',
[r+35, g+35, b+35].join(','),
')'
].join('');
color = feed.get('favicon_fade');
} else {
return [
'0 1px 0 ',
'rgb(',
[
parseInt(r*(6/8), 10),
parseInt(g*(6/8), 10),
parseInt(b*(6/8), 10)
].join(','),
')'
].join('');
color = feed.get('favicon_border');
}
r = parseInt(color.substr(0, 2), 16);
g = parseInt(color.substr(2, 2), 16);
b = parseInt(color.substr(4, 2), 16);
return [
'0 1px 0 ',
'rgb(',
[r, g, b].join(','),
')'
].join('');
}, function(feed) {
return "" + feed.id;
}),
@ -66,19 +58,27 @@ NEWSBLUR.utils = {
generate_gradient: _.memoize(function(feed, type) {
if (!feed) return '';
var color = feed.get('favicon_color');
var colorFade = feed.get('favicon_fade');
var colorBorder = feed.get('favicon_border');
if (!color) return '';
var r = parseInt(color.substr(0, 2), 16);
var g = parseInt(color.substr(2, 2), 16);
var b = parseInt(color.substr(4, 2), 16);
var rF = parseInt(colorFade.substr(0, 2), 16);
var gF = parseInt(colorFade.substr(2, 2), 16);
var bF = parseInt(colorFade.substr(4, 2), 16);
if (type == 'border') {
r = parseInt(colorBorder.substr(0, 2), 16);
g = parseInt(colorBorder.substr(2, 2), 16);
b = parseInt(colorBorder.substr(4, 2), 16);
return [
(type == 'border' ? '1px solid ' : '') + 'rgb(',
[
parseInt(r*(6/8), 10),
parseInt(g*(6/8), 10),
parseInt(b*(6/8), 10)
r,
g,
b
].join(','),
')'
].join('');
@ -98,9 +98,9 @@ NEWSBLUR.utils = {
')),',
'color-stop(1, rgba(',
[
r+35,
g+35,
b+35,
rF,
gF,
bF,
255
].join(','),
')))'
@ -118,9 +118,9 @@ NEWSBLUR.utils = {
') 0%,',
'rgb(',
[
r+35,
g+35,
b+35
rF,
gF,
bF
].join(','),
') 100%)'
].join('');

View file

@ -68,9 +68,21 @@ if __name__ == '__main__':
class S3Store:
def __init__(self, bucket_name=settings.S3_AVATARS_BUCKET_NAME):
if settings.DEBUG:
import ssl
try:
_create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
# Legacy Python that doesn't verify HTTPS certificates by default
pass
else:
# Handle target environment that doesn't support HTTPS verification
ssl._create_default_https_context = _create_unverified_https_context
self.s3 = S3Connection(ACCESS_KEY, SECRET)
self.bucket = self.create_bucket(bucket_name)
def create_bucket(self, bucket_name):
return self.s3.create_bucket(bucket_name)