Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 5 commits
  • 22 files changed
  • 0 comments
  • 1 contributor
1  Podfile
... ...
@@ -1,6 +1,5 @@
1 1
 platform :ios, "5.0"
2 2
 pod 'SDWebImage', '~> 3.0'
3  
-pod 'MHPrettyDate', '~> 1.0.1'
4 3
 pod 'MBProgressHUD', '~> 0.5'
5 4
 pod 'NSRails', :git => "https://github.com/huacnlee/nsrails.git", :branch => "with_cocopods"
6 5
 pod 'SSPullToRefresh', '~> 1.0.1'
3  Podfile.lock
... ...
@@ -1,7 +1,6 @@
1 1
 
2 2
 PODS:
3 3
 - MBProgressHUD (0.5)
4  
-- MHPrettyDate (1.0.1)
5 4
 - NSRails (2.0.1)
6 5
 - SDWebImage (3.0):
7 6
   - SDWebImage/Main (= 3.0)
@@ -11,7 +10,6 @@ PODS:
11 10
 
12 11
 DEPENDENCIES:
13 12
 - MBProgressHUD (~> 0.5)
14  
-- MHPrettyDate (~> 1.0.1)
15 13
 - NSRails (from `https://github.com/huacnlee/nsrails.git', branch `with_cocopods')
16 14
 - SDWebImage (~> 3.0)
17 15
 - SSPullToRefresh (~> 1.0.1)
@@ -24,7 +22,6 @@ EXTERNAL SOURCES:
24 22
 
25 23
 SPEC CHECKSUMS:
26 24
   MBProgressHUD: b23ee11c42253d6d804e8e0bfabdc334e8b2571f
27  
-  MHPrettyDate: 20779da456ad9c512a6a241929ac6cd53821794d
28 25
   NSRails: ca02b8858faddda7e57383571b56bb78ebf37d8e
29 26
   SDWebImage: afa3965bcb37797ba4ecac49393897b99d1b4be7
30 27
   SDWebImage/Main: afa3965bcb37797ba4ecac49393897b99d1b4be7
18  ruby-china-for-ios.xcodeproj/project.pbxproj
@@ -36,6 +36,10 @@
36 36
 		96A799301677709800F8A19E /* _reply.html in Resources */ = {isa = PBXBuildFile; fileRef = 96A7992F1677709800F8A19E /* _reply.html */; };
37 37
 		96A7993216777F8A00F8A19E /* Icon-114.png in Resources */ = {isa = PBXBuildFile; fileRef = 96A7993116777F8A00F8A19E /* Icon-114.png */; };
38 38
 		96A7993416777FA200F8A19E /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 96A7993316777FA200F8A19E /* Icon.png */; };
  39
+		96B0C277167832D4002DAF27 /* NSDate+TimeAgo.m in Sources */ = {isa = PBXBuildFile; fileRef = 96B0C276167832D4002DAF27 /* NSDate+TimeAgo.m */; };
  40
+		96B0C28216783BF2002DAF27 /* _no_replies.html in Resources */ = {isa = PBXBuildFile; fileRef = 96B0C28016783BF2002DAF27 /* _no_replies.html */; };
  41
+		96B0C28316783BF2002DAF27 /* _replies.html in Resources */ = {isa = PBXBuildFile; fileRef = 96B0C28116783BF2002DAF27 /* _replies.html */; };
  42
+		96B0C28616783D33002DAF27 /* _last_reply_info.html in Resources */ = {isa = PBXBuildFile; fileRef = 96B0C28516783D33002DAF27 /* _last_reply_info.html */; };
39 43
 		96EE8A3516760D1500DF5FE6 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96EE8A3416760D1500DF5FE6 /* CoreData.framework */; };
40 44
 		96FF7F831675D41500ADC02E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96FF7F821675D41500ADC02E /* UIKit.framework */; };
41 45
 		96FF7F851675D41500ADC02E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96FF7F841675D41500ADC02E /* Foundation.framework */; };
@@ -98,6 +102,11 @@
98 102
 		96A7992F1677709800F8A19E /* _reply.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = _reply.html; sourceTree = "<group>"; };
99 103
 		96A7993116777F8A00F8A19E /* Icon-114.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Icon-114.png"; path = "../Icon-114.png"; sourceTree = "<group>"; };
100 104
 		96A7993316777FA200F8A19E /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon.png; path = ../Icon.png; sourceTree = "<group>"; };
  105
+		96B0C275167832D4002DAF27 /* NSDate+TimeAgo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+TimeAgo.h"; sourceTree = "<group>"; };
  106
+		96B0C276167832D4002DAF27 /* NSDate+TimeAgo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+TimeAgo.m"; sourceTree = "<group>"; };
  107
+		96B0C28016783BF2002DAF27 /* _no_replies.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = _no_replies.html; sourceTree = "<group>"; };
  108
+		96B0C28116783BF2002DAF27 /* _replies.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = _replies.html; sourceTree = "<group>"; };
  109
+		96B0C28516783D33002DAF27 /* _last_reply_info.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = _last_reply_info.html; sourceTree = "<group>"; };
101 110
 		96EE8A3416760D1500DF5FE6 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
102 111
 		96FF7F7E1675D41500ADC02E /* ruby-china-for-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ruby-china-for-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; };
103 112
 		96FF7F821675D41500ADC02E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
@@ -236,7 +245,10 @@
236 245
 				96943654167631E000F1E1A9 /* default_avatar@2x.png */,
237 246
 				96FF7FB21675D70200ADC02E /* icons */,
238 247
 				96A7992A167762B900F8A19E /* topic_detail.html */,
  248
+				96B0C28516783D33002DAF27 /* _last_reply_info.html */,
239 249
 				96A7992F1677709800F8A19E /* _reply.html */,
  250
+				96B0C28016783BF2002DAF27 /* _no_replies.html */,
  251
+				96B0C28116783BF2002DAF27 /* _replies.html */,
240 252
 				96A7992D167763D900F8A19E /* topic_detail.css */,
241 253
 			);
242 254
 			path = Resources;
@@ -300,6 +312,8 @@
300 312
 				96FF81B31675EF9F00ADC02E /* RCRemoteObject.m */,
301 313
 				96FF81AC1675EDAF00ADC02E /* NSRRequest+Extend.h */,
302 314
 				96FF81AD1675EDAF00ADC02E /* NSRRequest+Extend.m */,
  315
+				96B0C275167832D4002DAF27 /* NSDate+TimeAgo.h */,
  316
+				96B0C276167832D4002DAF27 /* NSDate+TimeAgo.m */,
303 317
 			);
304 318
 			path = Categories;
305 319
 			sourceTree = "<group>";
@@ -404,6 +418,9 @@
404 418
 				96A799301677709800F8A19E /* _reply.html in Resources */,
405 419
 				96A7993216777F8A00F8A19E /* Icon-114.png in Resources */,
406 420
 				96A7993416777FA200F8A19E /* Icon.png in Resources */,
  421
+				96B0C28216783BF2002DAF27 /* _no_replies.html in Resources */,
  422
+				96B0C28316783BF2002DAF27 /* _replies.html in Resources */,
  423
+				96B0C28616783D33002DAF27 /* _last_reply_info.html in Resources */,
407 424
 			);
408 425
 			runOnlyForDeploymentPostprocessing = 0;
409 426
 		};
@@ -464,6 +481,7 @@
464 481
 				96943661167637D400F1E1A9 /* RCTopicViewController.m in Sources */,
465 482
 				9694366816763E8800F1E1A9 /* RCNavigationBar.m in Sources */,
466 483
 				96A4D0C91677282A000EAFAB /* RCNavLeftRightButtonItem.m in Sources */,
  484
+				96B0C277167832D4002DAF27 /* NSDate+TimeAgo.m in Sources */,
467 485
 			);
468 486
 			runOnlyForDeploymentPostprocessing = 0;
469 487
 		};
15  ruby-china-for-ios/Categories/NSDate+TimeAgo.h
... ...
@@ -0,0 +1,15 @@
  1
+//
  2
+//  NSDate+TimeAgo.h
  3
+//  ruby-china-for-ios
  4
+//
  5
+//  Created by Jason Lee on 12-12-12.
  6
+//  Copyright (c) 2012年 Ruby China. All rights reserved.
  7
+//
  8
+
  9
+#import <Foundation/Foundation.h>
  10
+
  11
+@interface NSDate (TimeAgo)
  12
+
  13
+- (NSString *) timeAgo;
  14
+
  15
+@end
79  ruby-china-for-ios/Categories/NSDate+TimeAgo.m
... ...
@@ -0,0 +1,79 @@
  1
+//
  2
+//  NSDate+TimeAgo.m
  3
+//  ruby-china-for-ios
  4
+//
  5
+//  Created by Jason Lee on 12-12-12.
  6
+//  Copyright (c) 2012年 Ruby China. All rights reserved.
  7
+//
  8
+
  9
+#import "NSDate+TimeAgo.h"
  10
+
  11
+@implementation NSDate (TimeAgo)
  12
+
  13
+- (NSString *) timeAgo {
  14
+    NSString *dateString;
  15
+    
  16
+    NSLog(@"timeAgo date: %@", self);
  17
+    
  18
+    // handle future date cases
  19
+    int days = [self daysFromNow];
  20
+    if (days > 200) {
  21
+        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  22
+        formatter.dateFormat = @"yyyy-MM-dd";
  23
+        dateString = [formatter stringFromDate:self];
  24
+    }
  25
+    else if (days > 31) {
  26
+        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  27
+        formatter.dateFormat = @"MM月dd日";
  28
+        dateString = [formatter stringFromDate:self];
  29
+    }
  30
+    else if (days == 0)  {
  31
+        if ([self hoursFromNow] == 0) {
  32
+            // if within 60 minutes print minutes
  33
+            NSInteger minutes = [self minutesFromNow];
  34
+            
  35
+            if (minutes == 0) {
  36
+                dateString = @"刚刚";
  37
+            }
  38
+            else {
  39
+                dateString = [NSString stringWithFormat: @"%d分钟前", minutes];
  40
+            }
  41
+        }
  42
+        else {
  43
+            // else print hours
  44
+            NSInteger hours = [self hoursFromNow];            
  45
+            dateString = [NSString stringWithFormat: @"%d小时前", hours];
  46
+        }
  47
+    }
  48
+    else if (days == 1) {
  49
+        dateString = @"昨天";
  50
+    }
  51
+    else if (days == 2) {
  52
+        dateString = @"两天前";
  53
+    }
  54
+    else {
  55
+        dateString = [NSString stringWithFormat: @"%d天前", days];
  56
+    }
  57
+    
  58
+    return dateString;
  59
+}
  60
+
  61
+
  62
+-(NSInteger) minutesFromNow {
  63
+    return ([self timeIntervalSinceNow] / 60) * -1;
  64
+}
  65
+
  66
+-(NSInteger) hoursFromNow {
  67
+    return ([self timeIntervalSinceNow] / (60 * 60)) * -1;
  68
+}
  69
+
  70
+-(NSInteger) daysFromNow{
  71
+    return ([self timeIntervalSinceNow] / ((60 * 60) * 24)) * -1;
  72
+}
  73
+
  74
+-(NSInteger) monthsForNow {
  75
+    return round([self daysFromNow] / 30.5) * -1;
  76
+}
  77
+
  78
+
  79
+@end
2  ruby-china-for-ios/Controllers/Components/RCNavigationBar.m
@@ -13,7 +13,7 @@ @implementation RCNavigationBar
13 13
 - (id)initWithCoder:(NSCoder *)aDecoder {
14 14
     self = [super initWithCoder:aDecoder];
15 15
     if (self) {
16  
-        self.backgroundColor = [UIColor clearColor];
  16
+        self.backgroundColor = [UIColor darkGrayColor];
17 17
         [self setBackgroundImage:[UIImage imageNamed:@"navbar_bg"] forBarMetrics:UIBarMetricsDefault];
18 18
     }
19 19
     return self;
46  ruby-china-for-ios/Controllers/Components/RCTopicTableViewCell.m
@@ -10,19 +10,21 @@
10 10
 #import "RCTopic.h"
11 11
 #import "RCUser.h"
12 12
 #import <SDWebImage/UIImageView+WebCache.h>
13  
-#import <MHPrettyDate.h>
14 13
 #import <SSToolkit/SSLabel.h>
15 14
 #import <SSToolkit/SSBadgeView.h>
16 15
 
17 16
 #define kTitleTextColor [UIColor colorWithRed:0.3255 green:0.3294 blue:0.3373 alpha:1.0000]
  17
+#define kTitleTextHighlightColor [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1.0000]
18 18
 #define kTitleFontSize 14
  19
+
19 20
 #define kSubTextColor [UIColor colorWithRed:0.8078 green:0.8118 blue:0.8196 alpha:1.0000]
  21
+#define kSubTextHighlightColor [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0000]
20 22
 #define kSubTextFontSize 12
21 23
 
22 24
 #define kBadgeColor [UIColor colorWithRed:0.1098 green:0.4980 blue:0.8588 alpha:1.0000]
23 25
 #define kBadgeWidth 40
24 26
 
25  
-#define kBackgrounImage [UIImage imageNamed:@"tableview_cell_bg.png"]
  27
+#define kBackgroundHighlightColor [UIColor colorWithRed:0.9686 green:0.9490 blue:0.9882 alpha:1.0000]
26 28
 #define kBorderTopImage [UIImage imageNamed:@"tableview_cell_border_top.png"]
27 29
 #define kBorderBottomImage [UIImage imageNamed:@"tableview_cell_border_bottom.png"]
28 30
 
@@ -38,8 +40,7 @@ - (id) initWithTopic: (RCTopic *) aTopic forDetail:(BOOL)isForDetail {
38 40
     topic = aTopic;
39 41
     
40 42
     if (self) {
41  
-        
42  
-//        self.backgroundColor = [UIColor whiteColor];
  43
+        self.selectionStyle = UITableViewCellSelectionStyleGray;
43 44
         
44 45
         avatarImageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 32, 32)];
45 46
         [avatarImageView setImageWithURL:[NSURL URLWithString:topic.user.avatarUrl] placeholderImage:[RCUser defaultAvatarImage]];
@@ -58,6 +59,7 @@ - (id) initWithTopic: (RCTopic *) aTopic forDetail:(BOOL)isForDetail {
58 59
         [titleLabel setText:topic.title];
59 60
         [titleLabel setFont:[UIFont systemFontOfSize:kTitleFontSize]];
60 61
         [titleLabel setTextColor:kTitleTextColor];
  62
+        [titleLabel setHighlightedTextColor:kTitleTextHighlightColor];
61 63
         [self.contentView addSubview:titleLabel];
62 64
         
63 65
         
@@ -69,39 +71,29 @@ - (id) initWithTopic: (RCTopic *) aTopic forDetail:(BOOL)isForDetail {
69 71
         infoLabel.backgroundColor = [UIColor clearColor];
70 72
         [infoLabel setFont:[UIFont systemFontOfSize:kSubTextFontSize]];
71 73
         [infoLabel setTextColor:kSubTextColor];
  74
+        [infoLabel setHighlightedTextColor:kSubTextHighlightColor];
72 75
         [self addSubview:infoLabel];
73 76
         
74  
-               
75  
-        if (isForDetail) {
76  
-            bodyLabel = [[UILabel alloc] initWithFrame:CGRectMake(titleLabel.frame.origin.x, infoLabel.frame.origin.y + 20, titleWidth, 14)];
77  
-            [bodyLabel setText:topic.bodyHtml];
78  
-            bodyLabel.backgroundColor = [UIColor clearColor];
79  
-            bodyLabel.font = [UIFont systemFontOfSize:13];
80  
-            bodyLabel.numberOfLines = 10;
81  
-            [bodyLabel setLineBreakMode:NSLineBreakByWordWrapping];
82  
-            bodyLabel.textAlignment = NSTextAlignmentLeft;
83  
-            [self addSubview:bodyLabel];
84  
-        }
85  
-        else {
86  
-            badgeView = [[SSBadgeView alloc] initWithFrame:CGRectMake(self.frame.size.width - kBadgeWidth - 10, 10, kBadgeWidth, 16)];
87  
-            badgeView.textLabel.text = [NSString stringWithFormat:@"%d",topic.repliesCount.intValue];
88  
-            badgeView.backgroundColor = [UIColor clearColor];
89  
-            badgeView.textLabel.font = [UIFont boldSystemFontOfSize:12.0f];
90  
-            badgeView.cornerRadius = 8;
91  
-            badgeView.badgeColor = kBadgeColor;
92  
-            badgeView.badgeAlignment = SSBadgeViewAlignmentRight;
93  
-            [self addSubview:badgeView];
94  
-        }
  77
+        badgeView = [[SSBadgeView alloc] initWithFrame:CGRectMake(self.frame.size.width - kBadgeWidth - 10, 10, kBadgeWidth, 16)];
  78
+        badgeView.textLabel.text = [NSString stringWithFormat:@"%d",topic.repliesCount.intValue];
  79
+        badgeView.backgroundColor = [UIColor clearColor];
  80
+        badgeView.textLabel.font = [UIFont boldSystemFontOfSize:12.0f];
  81
+        badgeView.cornerRadius = 8;
  82
+        badgeView.badgeColor = kBadgeColor;
  83
+        badgeView.highlightedBadgeColor = kBadgeColor;
  84
+        badgeView.textLabel.highlightedTextColor = [UIColor whiteColor];
  85
+        badgeView.badgeAlignment = SSBadgeViewAlignmentRight;
  86
+        [self addSubview:badgeView];
95 87
         
96 88
     }
97 89
     return self;
98 90
 }
99 91
 
100 92
 - (void) drawRect:(CGRect)rect {
  93
+    [super drawRect:rect];
101 94
     [kBorderTopImage drawInRect:CGRectMake(0, 0, self.frame.size.width, 1)];
102  
-    [kBackgrounImage drawInRect:CGRectMake(0, 1, self.frame.size.width, self.frame.size.height - 2)];
  95
+    //    [kBackgrounImage drawInRect:CGRectMake(0, 1, self.frame.size.width, self.frame.size.height - 2)];
103 96
     [kBorderBottomImage drawInRect:CGRectMake(0, self.frame.size.height - 1, self.frame.size.width, 1)];
104  
-    [super drawRect:rect];
105 97
 }
106 98
 
107 99
 
4  ruby-china-for-ios/Controllers/RCTopicViewController.h
@@ -9,10 +9,12 @@
9 9
 #import "RCViewController.h"
10 10
 
11 11
 @class RCTopic;
  12
+@class MBProgressHUD;
12 13
 
13  
-@interface RCTopicViewController : RCViewController <UIWebViewDelegate>  {
  14
+@interface RCTopicViewController : RCViewController <UIWebViewDelegate, UIScrollViewDelegate>  {
14 15
     RCTopic *topic;
15 16
     IBOutlet UIWebView *webView;
  17
+    MBProgressHUD *hud;
16 18
 }
17 19
 
18 20
 + (RCTopicViewController *) sharedInstance;
108  ruby-china-for-ios/Controllers/RCTopicViewController.m
@@ -11,7 +11,7 @@
11 11
 #import "RCAll.h"
12 12
 #import <MBProgressHUD.h>
13 13
 #import "RCNavigationBar.h"
14  
-#import <MHPrettyDate.h>
  14
+#import "NSDate+TimeAgo.h"
15 15
 
16 16
 #define kTopicDetailFileName @"topic_detail.html"
17 17
 
@@ -35,13 +35,12 @@ - (void)setTopic:(RCTopic *) aTopic {
35 35
 }
36 36
 
37 37
 - (void) loadRemoteInfo:(RCTopic *) aTopic {
38  
-//    MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
39  
-//    hud.mode = MBProgressHUDModeIndeterminate;
40  
-//    hud.labelText = @"载入中";
  38
+    [hud show:YES];
  39
+    [self setupBlankWebView];
41 40
     [RCTopic remoteObjectWithID:aTopic.remoteID async:^(id object, NSError *error) {
42 41
         topic = object;
43 42
         [self setupWebView];
44  
-//        [hud hide:YES];
  43
+        [hud hide:YES];
45 44
     }];
46 45
     
47 46
     
@@ -50,17 +49,48 @@ - (void) loadRemoteInfo:(RCTopic *) aTopic {
50 49
 - (void)viewDidLoad {
51 50
     [super viewDidLoad];
52 51
     
  52
+    hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
  53
+    hud.mode = MBProgressHUDModeIndeterminate;
  54
+    hud.labelText = @"载入中";
  55
+    
53 56
     UINavigationBar *navBar = self.navigationController.navigationBar;
54 57
     
55 58
     [navBar.backItem.backBarButtonItem setImage:[UIImage imageNamed:@"nav_back_icon"]];
56 59
     [navBar.backItem.backBarButtonItem setStyle:UIBarButtonItemStyleDone];
57 60
     
58 61
     webView.backgroundColor = [UIColor clearColor];
  62
+    webView.scrollView.bounces = NO;
  63
+    webView.scrollView.delegate = self;
  64
+    
  65
+    // MARK: 手势
  66
+    UISwipeGestureRecognizer *recognizerRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeToRight)];
  67
+    recognizerRight.direction = UISwipeGestureRecognizerDirectionRight;
  68
+    [webView addGestureRecognizer:recognizerRight];
  69
+    
  70
+    UISwipeGestureRecognizer *recognizerUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeToUp)];
  71
+    recognizerUp.direction = UISwipeGestureRecognizerDirectionUp;
  72
+    [webView addGestureRecognizer:recognizerUp];
  73
+    
  74
+    UISwipeGestureRecognizer *recognizerDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeToDown)];
  75
+    recognizerDown.direction = UISwipeGestureRecognizerDirectionDown;
  76
+    [webView addGestureRecognizer:recognizerDown];
  77
+}
  78
+
  79
+
  80
+#pragma mark - WebView
  81
+- (void) setupBlankWebView {
  82
+    NSString *html = @"";
  83
+    NSString *path = [[NSBundle mainBundle] bundlePath];
  84
+    NSURL *baseURL = [NSURL fileURLWithPath:path];
  85
+    [webView loadHTMLString:html baseURL:baseURL];
59 86
 }
60 87
 
61 88
 - (void) setupWebView {
62 89
     NSString *html = [self readTemplate:@"topic_detail"];
  90
+    NSString *repliesTemplate = [self readTemplate:@"_replies"];
  91
+    NSString *noRepliesTemplate = [self readTemplate:@"_no_replies"];
63 92
     NSString *_replyTemplate = [self readTemplate:@"_reply"];
  93
+    NSString *lastReplyInfo = [self readTemplate:@"_last_reply_info"];
64 94
     
65 95
     html = [self replaceHtml:html forKey:@"bundle_path" value:[[NSBundle mainBundle] resourcePath]];
66 96
     html = [self replaceHtml:html forKey:@"title" value:topic.title];
@@ -69,31 +99,42 @@ - (void) setupWebView {
69 99
     html = [self replaceHtml:html forKey:@"user_avatar_url" value:topic.user.avatarUrl];
70 100
     html = [self replaceHtml:html forKey:@"node_id" value:topic.nodeId];
71 101
     html = [self replaceHtml:html forKey:@"node_name" value:topic.nodeName];
72  
-    html = [self replaceHtml:html forKey:@"last_reply_user_login" value:topic.lastReplyUserLogin];
73  
-    html = [self replaceHtml:html forKey:@"replied_at" value:topic.repliedAt];
74  
-    html = [self replaceHtml:html forKey:@"hits" value:@""];
  102
+    if (topic.lastReplyUserLogin) {
  103
+        lastReplyInfo = [self replaceHtml:lastReplyInfo forKey:@"last_reply_user_login" value:topic.lastReplyUserLogin];
  104
+        lastReplyInfo = [self replaceHtml:lastReplyInfo forKey:@"replied_at" value:[topic.repliedAt timeAgo]];
  105
+    }
  106
+    else {
  107
+        lastReplyInfo = @"";
  108
+    }
  109
+    html = [self replaceHtml:html forKey:@"_last_reply_info" value:lastReplyInfo];
  110
+    html = [self replaceHtml:html forKey:@"created_at" value:[topic.createdAt timeAgo]];
  111
+    html = [self replaceHtml:html forKey:@"hits" value:topic.hits];
75 112
     html = [self replaceHtml:html forKey:@"replies_count" value:topic.repliesCount];
76 113
     
77 114
     NSMutableArray *replies = [NSMutableArray arrayWithCapacity:0];
78  
-    for (int i = 0; i < topic.replies.count; i ++) {
79  
-        RCReply *reply = [topic.replies objectAtIndex:i];
80  
-        NSString *replyHtml = [_replyTemplate copy];
  115
+    if (topic.replies.count > 0) {
  116
+        for (int i = 0; i < topic.replies.count; i ++) {
  117
+            RCReply *reply = [topic.replies objectAtIndex:i];
  118
+            NSString *replyHtml = [_replyTemplate copy];
  119
+            
  120
+            NSNumber *floor = [NSNumber numberWithInt:(i + 1)];
  121
+            
  122
+            replyHtml = [self replaceHtml:replyHtml forKey:@"floor" value:floor];
  123
+            replyHtml = [self replaceHtml:replyHtml forKey:@"reply.id" value:reply.remoteID];
  124
+            replyHtml = [self replaceHtml:replyHtml forKey:@"reply.user_login" value:reply.user.login];
  125
+            replyHtml = [self replaceHtml:replyHtml forKey:@"reply.user_avatar_url" value:reply.user.avatarUrl];
  126
+            replyHtml = [self replaceHtml:replyHtml forKey:@"reply.created_at" value:[reply.createdAt timeAgo]];
  127
+            replyHtml = [self replaceHtml:replyHtml forKey:@"reply.body_html" value:reply.bodyHtml];
  128
+            
  129
+            [replies addObject:replyHtml];
  130
+        }
81 131
         
82  
-        NSNumber *floor = [NSNumber numberWithInt:(i + 1)];
83  
-        
84  
-        replyHtml = [self replaceHtml:replyHtml forKey:@"floor" value:floor];
85  
-        replyHtml = [self replaceHtml:replyHtml forKey:@"reply.id" value:reply.remoteID];
86  
-        replyHtml = [self replaceHtml:replyHtml forKey:@"reply.user_login" value:reply.user.login];
87  
-        replyHtml = [self replaceHtml:replyHtml forKey:@"reply.user_avatar_url" value:reply.user.avatarUrl];
88  
-        replyHtml = [self replaceHtml:replyHtml forKey:@"reply.created_at" value:reply.createdAt];
89  
-        replyHtml = [self replaceHtml:replyHtml forKey:@"reply.body_html" value:reply.bodyHtml];
90  
-        
91  
-        [replies addObject:replyHtml];
  132
+        repliesTemplate = [self replaceHtml:repliesTemplate forKey:@"replies_collection" value:[replies componentsJoinedByString:@"\n"]];
  133
+        html = [self replaceHtml:html forKey:@"_replies" value:repliesTemplate];
  134
+    }
  135
+    else {
  136
+        html = [self replaceHtml:html forKey:@"_replies" value:noRepliesTemplate];
92 137
     }
93  
-    
94  
-    html = [self replaceHtml:html forKey:@"replies_collection" value:[replies componentsJoinedByString:@"\n"]];
95  
-    
96  
-    NSLog(@"%@",html);
97 138
     
98 139
     NSString *path = [[NSBundle mainBundle] bundlePath];
99 140
     NSURL *baseURL = [NSURL fileURLWithPath:path];
@@ -117,8 +158,7 @@ - (NSString *) replaceHtml:(NSString *)html forKey:(NSString *)key value:(id)val
117 158
         stringValue = [value stringValue];
118 159
     }
119 160
     else if ([value isKindOfClass:[NSDate class]]) {
120  
-        stringValue = [MHPrettyDate prettyDateFromDate:value
121  
-                                            withFormat:MHPrettyDateFormatWithTime];
  161
+        stringValue = [value timeAgo];
122 162
     }
123 163
 
124 164
     
@@ -126,4 +166,18 @@ - (NSString *) replaceHtml:(NSString *)html forKey:(NSString *)key value:(id)val
126 166
     html = [html stringByReplacingOccurrencesOfString:key withString:stringValue];
127 167
     return html;
128 168
 }
  169
+
  170
+#pragma mark - 手势
  171
+- (void)handleSwipeToRight {
  172
+    [self.navigationController popViewControllerAnimated:YES];
  173
+}
  174
+
  175
+- (void)handleSwipeToUp {
  176
+    [self.navigationController setNavigationBarHidden:NO animated:YES];
  177
+}
  178
+
  179
+- (void)handleSwipeToDown {
  180
+    [self.navigationController setNavigationBarHidden:YES animated:YES];
  181
+}
  182
+
129 183
 @end
10  ruby-china-for-ios/Controllers/RCTopicsViewController.m
@@ -10,6 +10,7 @@
10 10
 #import "RCTopicViewController.h"
11 11
 #import "RCTopicTableViewCell.h"
12 12
 #import "RCAll.h"
  13
+#import <SSPullToRefresh/SSPullToRefresh.h>
13 14
 
14 15
 @interface RCTopicsViewController ()
15 16
 
@@ -31,6 +32,10 @@ - (void)viewDidLoad
31 32
     [super viewDidLoad];
32 33
     
33 34
     pullToRefreshView = [[SSPullToRefreshView alloc] initWithScrollView:tableView delegate:self];
  35
+    SSPullToRefreshDefaultContentView *contentView = (SSPullToRefreshDefaultContentView *)pullToRefreshView.contentView;
  36
+    contentView.statusLabel.textColor = [UIColor grayColor];
  37
+    contentView.lastUpdatedAtLabel.textColor = [UIColor darkGrayColor];
  38
+    contentView.activityIndicatorView.color = [UIColor lightGrayColor];
34 39
     
35 40
     // MARK: UINavigationBar 设置
36 41
     UINavigationBar *navbar = self.navigationController.navigationBar;
@@ -77,10 +82,15 @@ - (void) refresh {
77 82
     [pullToRefreshView finishLoading];
78 83
 }
79 84
 
  85
+#pragma mark - PullToRefresh
80 86
 - (void) pullToRefreshViewDidStartLoading:(SSPullToRefreshView *)view {
81 87
     [self refresh];
82 88
 }
83 89
 
  90
+- (void)setState:(SSPullToRefreshViewState)state withPullToRefreshView:(SSPullToRefreshView *)view {
  91
+    
  92
+}
  93
+
84 94
 #pragma mark - TableView delegate
85 95
 - (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView {
86 96
     return 1;
2  ruby-china-for-ios/Models/RCTopic.h
@@ -18,7 +18,7 @@
18 18
 @property (nonatomic, strong) RCNode *node;
19 19
 @property (nonatomic, strong) NSMutableArray *replies;
20 20
 @property (nonatomic, strong) NSString *title, *body, *bodyHtml, *nodeName, *lastReplyUserLogin;
21  
-@property (nonatomic, strong) NSNumber *repliesCount, *lastReplyUserId, *nodeId;
  21
+@property (nonatomic, strong) NSNumber *repliesCount, *lastReplyUserId, *nodeId, *hits;
22 22
 @property (nonatomic, strong) NSDate *repliedAt, *createdAt, *updatedAt;
23 23
 
24 24
 @end
2  ruby-china-for-ios/Models/RCTopic.m
@@ -13,7 +13,7 @@
13 13
 #import "RCReply.h"
14 14
 
15 15
 @implementation RCTopic
16  
-@synthesize user, node, lastReplyUserId, lastReplyUserLogin, replies, title, body, bodyHtml, repliesCount, repliedAt, createdAt, updatedAt, nodeId, nodeName;
  16
+@synthesize user, node, lastReplyUserId, lastReplyUserLogin, replies, title, body, bodyHtml, repliesCount, repliedAt, createdAt, updatedAt, nodeId, nodeName, hits;
17 17
 
18 18
 - (Class) nestedClassForProperty:(NSString *)property
19 19
 {
3  ruby-china-for-ios/RCAppDelegate.m
@@ -23,8 +23,9 @@ @implementation RCAppDelegate
23 23
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
24 24
 {
25 25
     // Override point for customization after application launch.
  26
+    [NSRConfig defaultConfig].dateFormat = @"yyyy-MM-dd'T'HH:mm:sszz";
26 27
     [NSRConfig defaultConfig].appURL = kAPIURL;
27  
-    [NSRConfig defaultConfig].dateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'";;
  28
+
28 29
     return YES;
29 30
 }
30 31
 							
1  ruby-china-for-ios/Resources/_last_reply_info.html
... ...
@@ -0,0 +1 @@
  1
+• <span>最后由 <a href="/{{last_reply_user_login}}">{{last_reply_user_login}}</a> 于<abbr class="timeago" title="">{{replied_at}}</abbr>回复</span>
3  ruby-china-for-ios/Resources/_no_replies.html
... ...
@@ -0,0 +1,3 @@
  1
+<div id="no_replies">
  2
+暂时无人对此话题回复过,就等你了!
  3
+</div>
8  ruby-china-for-ios/Resources/_replies.html
... ...
@@ -0,0 +1,8 @@
  1
+<div id="replies" class="box box_gray">
  2
+  <div class="total">
  3
+    共收到 <b>{{replies_count}}</b> 条回复
  4
+  </div>
  5
+  <div class="items">
  6
+      {{replies_collection}}
  7
+  </div>
  8
+</div>
2  ruby-china-for-ios/Resources/_reply.html
@@ -4,7 +4,7 @@
4 4
       <div class="info">
5 5
         <span class="name">
6 6
           <a href="/{{reply.user_login}}" data-name="">{{reply.user_login}}</a>
7  
-          {{floor}}楼, <abbr class="timeago" title="{{reply.created_at}}"></abbr>
  7
+          {{floor}}楼, <abbr class="timeago">{{reply.created_at}}</abbr>
8 8
         </span>
9 9
       </div>
10 10
       <div class="body">
BIN  ruby-china-for-ios/Resources/navbar_bg.png
BIN  ruby-china-for-ios/Resources/navbar_bg@2x.png
16  ruby-china-for-ios/Resources/topic_detail.css
@@ -76,6 +76,13 @@ p {
76 76
   background: #F5F5F5;
77 77
 }
78 78
 
  79
+#no_replies {
  80
+    font-size:12px;
  81
+    color:#aaa;
  82
+    text-align:center;
  83
+    margin:10px;
  84
+}
  85
+
79 86
 .topics .topic .avatar {
80 87
   width: 56px;
81 88
   margin-left: 10px;
@@ -96,6 +103,15 @@ p {
96 103
   margin-bottom: 2px;
97 104
   font-size: 12px;
98 105
 }
  106
+.topics .topic .info abbr { margin:0 4px; }
  107
+.topics .last_info {
  108
+    color:#999;
  109
+}
  110
+
  111
+.topics .topic span,
  112
+.topics .topic code,
  113
+.topics .topic a { display:inline-block; }
  114
+
99 115
 .topics .topic .info .node {
100 116
   padding: 1px 5px;
101 117
   color: #778087;
25  ruby-china-for-ios/Resources/topic_detail.html
@@ -17,32 +17,23 @@
17 17
         </div>
18 18
         <h1 class="entry-title">{{title}}</h1>
19 19
         <div class="info leader">
20  
-          <a href="/topics/node{{node_id}}" class="node">{{node_name}}</a>
21  
-          •
22  
-          <a href="/{{user_login}}">{{user_login}}</a>
23  
-          •
24  
-          于<abbr class="timeago" title="{{created_at}}"></abbr>发布
25  
-            •
26  
-            最后由 <a href="/{{last_reply_user_login}}">{{last_reply_user_login}}</a> 于<abbr class="timeago" title="{{replied_at}}"></abbr>回复
27  
-          •
28  
-            {{hits}}次阅读
  20
+          <span><a href="/topics/node{{node_id}}" class="node">{{node_name}}</a></span>
  21
+          •<span><a href="/{{user_login}}">{{user_login}}</a></span>
  22
+          • <span>于<abbr class="timeago" title="">{{created_at}}</abbr>发布</span> 
  23
+          {{_last_reply_info}}
29 24
         </div>
30 25
       </div>
31 26
 
32 27
       <div class="body entry-content" id="topic_body">
33 28
         {{body_html}}
34 29
       </div>
  30
+      <div class="last_info">
  31
+        <span>{{hits}}次阅读</span>
  32
+      </div>
35 33
     </div>
36 34
   </div>
37 35
 
38  
-  <div id="replies" class="box box_gray">
39  
-    <div class="total">
40  
-      共收到 <b>{{replies_count}}</b> 条回复
41  
-    </div>
42  
-    <div class="items">
43  
-        {{replies_collection}}
44  
-    </div>
45  
-  </div>
  36
+  {{_replies}}
46 37
 </div>
47 38
 </body>
48 39
 </html>
23  ruby-china-for-ios/en.lproj/MainStoryboard.storyboard
... ...
@@ -1,17 +1,25 @@
1 1
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2  
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="2840" systemVersion="12C60" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="fFC-Jr-qJp">
  2
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="2844" systemVersion="12C60" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="fFC-Jr-qJp">
3 3
     <dependencies>
4  
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="1926"/>
  4
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="1930"/>
5 5
     </dependencies>
6 6
     <scenes>
7 7
         <!--Navigation Controller-->
8 8
         <scene sceneID="EIv-Ds-9F1">
9 9
             <objects>
10  
-                <navigationController definesPresentationContext="YES" id="fFC-Jr-qJp" sceneMemberID="viewController">
11  
-                    <navigationBar key="navigationBar" alpha="0.80000000000000004" contentMode="top" id="kso-3n-e9T" customClass="RCNavigationBar">
  10
+                <navigationController definesPresentationContext="YES" toolbarHidden="NO" id="fFC-Jr-qJp" sceneMemberID="viewController">
  11
+                    <simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
  12
+                    <simulatedNavigationBarMetrics key="simulatedTopBarMetrics" barStyle="blackOpaque" prompted="NO"/>
  13
+                    <simulatedToolbarMetrics key="simulatedBottomBarMetrics" barStyle="blackOpaque"/>
  14
+                    <navigationBar key="navigationBar" alpha="0.80000000000000004" contentMode="top" barStyle="blackOpaque" id="kso-3n-e9T" customClass="RCNavigationBar">
  15
+                        <rect key="frame" x="0.0" y="0.0" width="0.0" height="44"/>
12 16
                         <autoresizingMask key="autoresizingMask"/>
13 17
                         <color key="backgroundColor" white="0.65738407258064513" alpha="1" colorSpace="calibratedWhite"/>
14 18
                     </navigationBar>
  19
+                    <toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" barStyle="blackOpaque" id="ucj-eH-FSd">
  20
+                        <rect key="frame" x="0.0" y="524" width="320" height="44"/>
  21
+                        <autoresizingMask key="autoresizingMask"/>
  22
+                    </toolbar>
15 23
                     <connections>
16 24
                         <segue destination="2" kind="relationship" relationship="rootViewController" id="pmm-T7-Oid"/>
17 25
                     </connections>
@@ -25,7 +33,7 @@
25 33
             <objects>
26 34
                 <viewController title="话题列表" id="2" customClass="RCTopicsViewController" sceneMemberID="viewController">
27 35
                     <view key="view" contentMode="scaleToFill" id="16">
28  
-                        <rect key="frame" x="0.0" y="64" width="320" height="504"/>
  36
+                        <rect key="frame" x="0.0" y="64" width="320" height="460"/>
29 37
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
30 38
                         <subviews>
31 39
                             <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="FI3-mE-5lq" customClass="RCTableView">
@@ -53,7 +61,7 @@
53 61
                 </viewController>
54 62
                 <placeholder placeholderIdentifier="IBFirstResponder" id="10" sceneMemberID="firstResponder"/>
55 63
             </objects>
56  
-            <point key="canvasLocation" x="580" y="286"/>
  64
+            <point key="canvasLocation" x="436" y="338"/>
57 65
         </scene>
58 66
         <!--Topic View Controller - 查看话题-->
59 67
         <scene sceneID="6iy-Mq-517">
@@ -65,6 +73,7 @@
65 73
                         <subviews>
66 74
                             <webView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bB2-28-A08">
67 75
                                 <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
  76
+                                <dataDetectorType key="dataDetectorTypes"/>
68 77
                                 <connections>
69 78
                                     <outlet property="delegate" destination="Ict-Dp-uwZ" id="Cu0-if-8FJ"/>
70 79
                                 </connections>
@@ -86,7 +95,7 @@
86 95
                 </viewController>
87 96
                 <placeholder placeholderIdentifier="IBFirstResponder" id="1ds-Er-6ft" userLabel="First Responder" sceneMemberID="firstResponder"/>
88 97
             </objects>
89  
-            <point key="canvasLocation" x="916" y="893"/>
  98
+            <point key="canvasLocation" x="-130" y="1024"/>
90 99
         </scene>
91 100
     </scenes>
92 101
     <resources>

No commit comments for this range

Something went wrong with that request. Please try again.