├── .gitignore
├── .gitmodules
├── API Problem.md
├── CHANGES.md
├── JLRubyChina.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ └── JLRubyChina.xccheckout
├── JLRubyChina.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
│ └── JLRubyChina.xccheckout
├── JLRubyChina
├── Categories
│ ├── NSDate+RubyChina.h
│ ├── NSDate+RubyChina.m
│ ├── NSString+stringFromValue.h
│ ├── NSString+stringFromValue.m
│ ├── UIImage+nimbusImageNamed.h
│ ├── UIImage+nimbusImageNamed.m
│ ├── UIView+findViewController.h
│ └── UIView+findViewController.m
├── Common
│ ├── RCAPIClient.h
│ ├── RCAPIClient.m
│ └── RCJSONKeys.h
├── Controller
│ ├── RCAboutAppC.h
│ ├── RCAboutAppC.m
│ ├── RCAboutAppC.xib
│ ├── RCContentPhotoBrowerC.h
│ ├── RCContentPhotoBrowerC.m
│ ├── RCCoolSitesC.h
│ ├── RCCoolSitesC.m
│ ├── RCForumNodesC.h
│ ├── RCForumNodesC.m
│ ├── RCForumTopicsC.h
│ ├── RCForumTopicsC.m
│ ├── RCLeftMenuC.h
│ ├── RCLeftMenuC.m
│ ├── RCLoginC.h
│ ├── RCLoginC.m
│ ├── RCMoreC.h
│ ├── RCMoreC.m
│ ├── RCNodesCloudTagC.h
│ ├── RCNodesCloudTagC.m
│ ├── RCPostC.h
│ ├── RCPostC.m
│ ├── RCQuickReplyC.h
│ ├── RCQuickReplyC.m
│ ├── RCTopMembersC.h
│ ├── RCTopMembersC.m
│ ├── RCTopMembersC_list.h
│ ├── RCTopMembersC_list.m
│ ├── RCTopicDetailC.h
│ ├── RCTopicDetailC.m
│ ├── RCUserHomepageC.h
│ ├── RCUserHomepageC.m
│ ├── RCWikiC.h
│ └── RCWikiC.m
├── Entities
│ ├── RCAccountEntity.h
│ ├── RCAccountEntity.m
│ ├── RCKeywordEntity.h
│ ├── RCKeywordEntity.m
│ ├── RCNodeEntity.h
│ ├── RCNodeEntity.m
│ ├── RCNodeSectionEntity.h
│ ├── RCNodeSectionEntity.m
│ ├── RCReplyEntity.h
│ ├── RCReplyEntity.m
│ ├── RCSiteEntity.h
│ ├── RCSiteEntity.m
│ ├── RCSiteSectionEntity.h
│ ├── RCSiteSectionEntity.m
│ ├── RCTopicDetailEntity.h
│ ├── RCTopicDetailEntity.m
│ ├── RCTopicEntity.h
│ ├── RCTopicEntity.m
│ ├── RCUserEntity.h
│ ├── RCUserEntity.m
│ ├── RCUserFullEntity.h
│ └── RCUserFullEntity.m
├── JLRubyChina-Dis-Info.plist
├── JLRubyChina-Info.plist
├── JLRubyChina-Prefix.pch
├── JLTesterHome-Dis-Info.plist
├── JLTesterHome-Info.plist
├── JLV2EX-Info.plist
├── MacroDefines.h
├── Models
│ ├── RCBaseTableModel.h
│ ├── RCBaseTableModel.m
│ ├── RCCoolSitesModel.h
│ ├── RCCoolSitesModel.m
│ ├── RCForumNodesModel.h
│ ├── RCForumNodesModel.m
│ ├── RCForumTopicsModel.h
│ ├── RCForumTopicsModel.m
│ ├── RCLoginModel.h
│ ├── RCLoginModel.m
│ ├── RCPostModel.h
│ ├── RCPostModel.m
│ ├── RCReplyModel.h
│ ├── RCReplyModel.m
│ ├── RCTopMembersModel.h
│ ├── RCTopMembersModel.m
│ ├── RCTopMembersModel_list.h
│ ├── RCTopMembersModel_list.m
│ ├── RCTopicActionModel.h
│ ├── RCTopicActionModel.m
│ ├── RCTopicDetailModel.h
│ ├── RCTopicDetailModel.m
│ ├── RCUserHomepageModel.h
│ └── RCUserHomepageModel.m
├── RCAppDelegate.h
├── RCAppDelegate.m
├── RCGlobalConfig.h
├── RCGlobalConfig.m
├── Util
│ ├── RCRegularParser.h
│ └── RCRegularParser.m
├── Views
│ ├── RCHomepageHeaderView.h
│ ├── RCHomepageHeaderView.m
│ ├── RCNodeCell.h
│ ├── RCNodeCell.m
│ ├── RCReplyCell.h
│ ├── RCReplyCell.m
│ ├── RCSiteCell.h
│ ├── RCSiteCell.m
│ ├── RCTopicBodyView.h
│ ├── RCTopicBodyView.m
│ ├── RCTopicCell.h
│ ├── RCTopicCell.m
│ ├── RCUserCell.h
│ ├── RCUserCell.m
│ ├── RCUserLauncherButtonView.h
│ └── RCUserLauncherButtonView.m
├── en.lproj
│ └── InfoPlist.strings
└── main.m
├── JLRubyChinaTests
├── JLRubyChinaTests-Info.plist
├── JLRubyChinaTests.m
└── en.lproj
│ └── InfoPlist.strings
├── Podfile
├── Podfile.lock
├── README.md
├── Resource
├── Images
│ ├── Common
│ │ ├── 37x-Checkmark.png
│ │ ├── 37x-Checkmark@2x.png
│ │ ├── QuickReply
│ │ │ ├── MessageEntryBackground.png
│ │ │ ├── MessageEntryBackground@2x.png
│ │ │ ├── MessageEntryInputField.png
│ │ │ ├── MessageEntryInputField@2x.png
│ │ │ ├── MessageEntrySendButton.png
│ │ │ ├── MessageEntrySendButton@2x.png
│ │ │ ├── MessageEntrySendButtonPressed.png
│ │ │ └── MessageEntrySendButtonPressed@2x.png
│ │ ├── head_b.png
│ │ ├── head_b@2x.png
│ │ ├── head_s.png
│ │ ├── head_s@2x.png
│ │ ├── icon_menu.png
│ │ ├── icon_menu@2x.png
│ │ ├── more_photo.png
│ │ └── more_photo@2x.png
│ └── Forums
│ │ ├── RubyChina
│ │ └── IconDefault
│ │ │ ├── Default-375w-667h@2x.png
│ │ │ ├── Default-414w-736h@3x.png
│ │ │ ├── Default-568h@2x.png
│ │ │ ├── Default.png
│ │ │ ├── Default@2x.png
│ │ │ ├── icon.png
│ │ │ ├── icon
│ │ │ ├── icon.png
│ │ │ ├── icon120.png
│ │ │ ├── icon58.png
│ │ │ ├── icon80.png
│ │ │ ├── icon@2x.png
│ │ │ └── logo512.png
│ │ │ ├── icon120.png
│ │ │ ├── icon512.png
│ │ │ ├── icon58.png
│ │ │ ├── icon80.png
│ │ │ ├── icon@2x.png
│ │ │ ├── pure_icon@2x.png
│ │ │ ├── ruby-logo.png
│ │ │ └── ruby-logo@2x.png
│ │ ├── TesterHome
│ │ └── IconDefault
│ │ │ ├── Default-568h@2x.png
│ │ │ ├── Default.png
│ │ │ ├── Default@2x.png
│ │ │ ├── icon.png
│ │ │ ├── icon120.png
│ │ │ ├── icon58.png
│ │ │ ├── icon80.png
│ │ │ ├── icon@2x.png
│ │ │ ├── ruby-logo.png
│ │ │ └── ruby-logo@2x.png
│ │ └── V2EX
│ │ ├── IconDefault
│ │ ├── Default-568h@2x.png
│ │ ├── Default.png
│ │ ├── Default@2x.png
│ │ ├── icon.png
│ │ ├── icon120.png
│ │ ├── icon58.png
│ │ ├── icon80.png
│ │ ├── icon@2x.png
│ │ ├── logo.png
│ │ ├── ruby-logo.png
│ │ └── ruby-logo@2x.png
│ │ └── Screenshots
│ │ ├── 0110_1.png
│ │ ├── 0110_2.png
│ │ └── 0110_3.png
└── Screenshots
│ ├── ErrorResolve
│ ├── not_found_pods.png
│ └── open_xcworkspace.jpg
│ ├── default.png
│ ├── home_activity_topics.png
│ ├── home_page.png
│ ├── left_menu_side.png
│ ├── more.png
│ ├── node_select.png
│ ├── nodes.png
│ ├── outside_link_sites.png
│ ├── top_members.png
│ └── topic_reply.png
├── TODO.md
└── vendor
└── Reachability
├── Reachability.h
└── Reachability.m
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | */build/*
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | profile
14 | *.moved-aside
15 | DerivedData
16 | .idea/
17 | *.hmap
18 |
19 | #CocoaPods
20 | Pods
21 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "vendor/TSEmojiView"]
2 | path = vendor/TSEmojiView
3 | url = https://github.com/jimneylee/TSEmojiView.git
4 | [submodule "vendor/JLNimbusTimeline"]
5 | path = vendor/JLNimbusTimeline
6 | url = https://github.com/jimneylee/JLNimbusTimeline.git
7 | [submodule "vendor/JASidePanels"]
8 | path = vendor/JASidePanels
9 | url = https://github.com/gotosleep/JASidePanels.git
10 | [submodule "vendor/MarkdownSyntaxEditor"]
11 | path = vendor/MarkdownSyntaxEditor
12 | url = https://github.com/jimneylee/MarkdownSyntaxEditor.git
13 | [submodule "vendor/320Categories"]
14 | path = vendor/320Categories
15 | url = https://github.com/jimneylee/320Categories.git
16 |
--------------------------------------------------------------------------------
/API Problem.md:
--------------------------------------------------------------------------------
1 | 社区API开放接口问题反馈
2 |
3 | 后台API接口有几个还需要完善下,具体问题如下:
4 | 1、帖子回复列表:
5 | API: http://ruby-china.org/api/topics/16194.json
6 |
7 | * a、回复列表未按id排序,会错乱,建议在接口中处理。
8 | 参照帖子:http://ruby-china.org/topics/16194
9 |
10 | * b、已删除的楼层,在回复列表数据中无法判断
11 | 接口数据建议放一个占位数据,客户端解析发帖没有id,认为帖子已删除。跟网页一致显示已删除。保证楼层跳转正确。
12 |
13 | 3、帖子的(取消)关注成功返回是json、(取消)关注失败返回是false,而收藏成功返回是true or false
14 | API: http://ruby-china.org/api/v2/topics/:id/follow.json
15 | API: http://ruby-china.org/api/v2/topics/:id/unfollow.json
16 | API: http://ruby-china.org/api/v2/topics/:id/favorite.json
17 | 返回结果不统一,建议统一格式返回
18 |
19 | 4、个人主页接口中最近5条帖子的信息不完整
20 | API: http://ruby-china.org/api/users/:user.json
21 |
22 | 5、建议增加精华贴接口,这样方便大家通过客户端查阅社区优秀的帖子
23 |
24 | 6、http://ruby-china.org/api/topics.json 默认是热门贴。
25 | 建议增加一个type类型,实现分类查看: 默认 / 优质帖子 / 无人问津 / 最新创建
26 |
27 | 望采纳!Merry Christmas!
--------------------------------------------------------------------------------
/CHANGES.md:
--------------------------------------------------------------------------------
1 | ****************************************************
2 | V1.2.0
3 | 1、修复表情显示不完整问题
4 | 2、修复回复多行,回复按钮无法点击问题
5 | 3、修复第一个回复崩溃的问题
6 | 4、修复回复列表未排序的问题
7 |
8 | ****************************************************
9 | V1.1.1
10 | 1、帖子正文支持markdown语法,正则匹配还有很多问题,待完善
11 | 2、显示帖子和回复中图片
12 | 3、兼容ios6
13 | 4、添加网络断开/2g3g/wifi切换的时间侦听和提示
14 |
15 | ****************************************************
16 | V1.1.0
17 | 1、回复支持表情选择功能
18 | 2、发帖支持markdown语法
19 |
20 | ****************************************************
21 | V1.0.0
22 | 1、首页热门帖子显示
23 | 2、帖子详细浏览、帖子回复列表,待支持markdown语法解析显示
24 | 3、帖子关注、收藏、回复及@某人
25 | 4、发帖到指定分类,待支持表情选择
26 | 5、分类节点列表查看,待做分组与排序
27 | 6、酷站分组显示
28 | 7、会员TOP N查看
29 | 8、我的主页,已发帖子、收藏帖子查看,待做详细资料
30 | 9、Ruby China Wiki
31 | 10、更多功能包含:清空缓存、更新检测、给我评分、关于APP
--------------------------------------------------------------------------------
/JLRubyChina.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/JLRubyChina.xcodeproj/project.xcworkspace/xcshareddata/JLRubyChina.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 7D4F33C3-4B34-48A4-904B-63B784DE6E8F
9 | IDESourceControlProjectName
10 | JLRubyChina
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 89A2599F-171F-4ABC-B940-6960B71B8B35
14 | https://git.oschina.net/jimneylee/JLRubyChina-iPhone.git
15 |
16 | IDESourceControlProjectPath
17 | JLRubyChina.xcodeproj/project.xcworkspace
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | 89A2599F-171F-4ABC-B940-6960B71B8B35
21 | ../..
22 |
23 | IDESourceControlProjectURL
24 | https://git.oschina.net/jimneylee/JLRubyChina-iPhone.git
25 | IDESourceControlProjectVersion
26 | 110
27 | IDESourceControlProjectWCCIdentifier
28 | 89A2599F-171F-4ABC-B940-6960B71B8B35
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | 89A2599F-171F-4ABC-B940-6960B71B8B35
36 | IDESourceControlWCCName
37 | JLRubyChina-iPhone
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/JLRubyChina.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/JLRubyChina.xcworkspace/xcshareddata/JLRubyChina.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | D7E329C1-831E-4961-BC5F-DCF0760536B7
9 | IDESourceControlProjectName
10 | JLRubyChina
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 3696B39AF9A7D45AA2A36BD621E04A71FEC24306
14 | https://github.com/jimneylee/JLNimbusTimeline.git
15 | 61BE18A5930DA2ABE9DDA67B3F71C81D12CD46A9
16 | https://github.com/gotosleep/JASidePanels.git
17 | A0EA22F907A77FD19F76C743593B2249B390F456
18 | https://github.com/jimneylee/MarkdownSyntaxEditor.git
19 | B12BDDCD638DC62B878AE944EF431929C4E405C0
20 | https://github.com/jimneylee/JLRubyChina-iPhone.git
21 | E252D7BD2F0F58EA499CABA45B3A8E07286F0E94
22 | https://github.com/jimneylee/320Categories.git
23 | F0BB51E5AD498528F60E05CFD675B5B2ED0B3A2B
24 | https://github.com/jimneylee/TSEmojiView.git
25 |
26 | IDESourceControlProjectPath
27 | JLRubyChina.xcworkspace
28 | IDESourceControlProjectRelativeInstallPathDictionary
29 |
30 | 3696B39AF9A7D45AA2A36BD621E04A71FEC24306
31 | ../vendor/JLNimbusTimeline
32 | 61BE18A5930DA2ABE9DDA67B3F71C81D12CD46A9
33 | ../vendor/JASidePanels
34 | A0EA22F907A77FD19F76C743593B2249B390F456
35 | ../vendor/MarkdownSyntaxEditor
36 | B12BDDCD638DC62B878AE944EF431929C4E405C0
37 | ..
38 | E252D7BD2F0F58EA499CABA45B3A8E07286F0E94
39 | ../vendor/320Categories
40 | F0BB51E5AD498528F60E05CFD675B5B2ED0B3A2B
41 | ../vendor/TSEmojiView
42 |
43 | IDESourceControlProjectURL
44 | https://github.com/jimneylee/JLRubyChina-iPhone.git
45 | IDESourceControlProjectVersion
46 | 111
47 | IDESourceControlProjectWCCIdentifier
48 | B12BDDCD638DC62B878AE944EF431929C4E405C0
49 | IDESourceControlProjectWCConfigurations
50 |
51 |
52 | IDESourceControlRepositoryExtensionIdentifierKey
53 | public.vcs.git
54 | IDESourceControlWCCIdentifierKey
55 | E252D7BD2F0F58EA499CABA45B3A8E07286F0E94
56 | IDESourceControlWCCName
57 | 320Categories
58 |
59 |
60 | IDESourceControlRepositoryExtensionIdentifierKey
61 | public.vcs.git
62 | IDESourceControlWCCIdentifierKey
63 | 61BE18A5930DA2ABE9DDA67B3F71C81D12CD46A9
64 | IDESourceControlWCCName
65 | JASidePanels
66 |
67 |
68 | IDESourceControlRepositoryExtensionIdentifierKey
69 | public.vcs.git
70 | IDESourceControlWCCIdentifierKey
71 | 3696B39AF9A7D45AA2A36BD621E04A71FEC24306
72 | IDESourceControlWCCName
73 | JLNimbusTimeline
74 |
75 |
76 | IDESourceControlRepositoryExtensionIdentifierKey
77 | public.vcs.git
78 | IDESourceControlWCCIdentifierKey
79 | B12BDDCD638DC62B878AE944EF431929C4E405C0
80 | IDESourceControlWCCName
81 | JLRubyChina-iPhone
82 |
83 |
84 | IDESourceControlRepositoryExtensionIdentifierKey
85 | public.vcs.git
86 | IDESourceControlWCCIdentifierKey
87 | A0EA22F907A77FD19F76C743593B2249B390F456
88 | IDESourceControlWCCName
89 | MarkdownSyntaxEditor
90 |
91 |
92 | IDESourceControlRepositoryExtensionIdentifierKey
93 | public.vcs.git
94 | IDESourceControlWCCIdentifierKey
95 | F0BB51E5AD498528F60E05CFD675B5B2ED0B3A2B
96 | IDESourceControlWCCName
97 | TSEmojiView
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/JLRubyChina/Categories/NSDate+RubyChina.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSDate+RubyChina.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSDate (RubyChina)
12 |
13 | + (NSDate*)dateFromSourceDateString:(NSString*)dateString;
14 |
15 | + (NSDate *)formatDateWith_T_FromString:(NSString *)dateString;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/JLRubyChina/Categories/NSDate+RubyChina.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSDate+RubyChina.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "NSDate+RubyChina.h"
10 |
11 | @implementation NSDate (RubyChina)
12 |
13 | ///////////////////////////////////////////////////////////////////////////////////////////////////
14 | + (NSDate*)dateFromSourceDateString:(NSString*)dateString
15 | {
16 | NSDate* date = nil;
17 | NSRange range = NSMakeRange(0, 0);
18 | if (dateString && [dateString isKindOfClass:[NSString class]] && dateString.length) {
19 | //2013-12-10T20:17:42.707+08:00
20 | range = [dateString rangeOfString:@"."];
21 | if (range.length) {
22 | dateString = [dateString substringToIndex:range.location];
23 | }
24 | date = [NSDate formatDateWith_T_FromString:dateString];
25 | }
26 | return date;
27 | }
28 |
29 | ///////////////////////////////////////////////////////////////////////////////////////////////////
30 | + (NSDate *)formatDateWith_T_FromString:(NSString *)string {
31 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
32 | [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'+08:00'"];
33 | return [dateFormatter dateFromString:string];
34 | }
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/JLRubyChina/Categories/NSString+stringFromValue.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+stringFromValue.h
3 | // SinaMBlogNimbus
4 | //
5 | // Created by jimneylee on 13-10-14.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSString (stringFromValue)
12 |
13 | + (NSString*)stringFromValue:(id)value;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/JLRubyChina/Categories/NSString+stringFromValue.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+stringFromValue.m
3 | // SinaMBlogNimbus
4 | //
5 | // Created by jimneylee on 13-10-14.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "NSString+stringFromValue.h"
10 |
11 | @implementation NSString (stringFromValue)
12 |
13 | + (NSString*)stringFromValue:(id)value
14 | {
15 | if (value) {
16 | if ([value isKindOfClass:[NSString class]]) {
17 | return value;
18 | }
19 | else if ([value isKindOfClass:[NSNumber class]]) {
20 | return [value stringValue];
21 | }
22 | else {
23 | return @"";
24 | }
25 | }
26 | else {
27 | return @"";
28 | }
29 | }
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/JLRubyChina/Categories/UIImage+nimbusImageNamed.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+nimbusImageNamed.h
3 | // SinaMBlogNimbus
4 | //
5 | // Created by Lee jimney on 10/7/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIImage (nimbusImageNamed)
12 |
13 | + (UIImage*)nimbusImageNamed:(NSString*)imageName;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/JLRubyChina/Categories/UIImage+nimbusImageNamed.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+nimbusImageNamed.m
3 | // SinaMBlogNimbus
4 | //
5 | // Created by Lee jimney on 10/7/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "UIImage+nimbusImageNamed.h"
10 |
11 | @implementation UIImage (nimbusImageNamed)
12 |
13 | + (UIImage*)nimbusImageNamed:(NSString*)imageName
14 | {
15 | NSString* imagePath = NIPathForBundleResource(nil, imageName);
16 | UIImage* image = [[Nimbus imageMemoryCache] objectWithName:imagePath];
17 | if (nil == image) {
18 | image = [UIImage imageWithContentsOfFile:imagePath];
19 | // And then store it in memory.
20 | [[Nimbus imageMemoryCache] storeObject:image withName:imagePath];
21 | }
22 | return image;
23 | }
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/JLRubyChina/Categories/UIView+findViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+findViewController.h
3 | // SinaMBlogNimbus
4 | //
5 | // Created by jimneylee on 13-12-2.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIView (findViewController)
12 |
13 | - (UIViewController *)viewController;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/JLRubyChina/Categories/UIView+findViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+findViewController.m
3 | // SinaMBlogNimbus
4 | //
5 | // Created by jimneylee on 13-12-2.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "UIView+findViewController.h"
10 |
11 | @implementation UIView (findViewController)
12 | - (UIViewController *)viewController {
13 | // Traverse responder chain. Return first found view controller, which will be the view's view controller.
14 | UIResponder *responder = self;
15 | while ((responder = [responder nextResponder]))
16 | if ([responder isKindOfClass:[UIViewController class]])
17 | return (UIViewController *)responder;
18 |
19 | // If the view controller isn't found, return nil.
20 | return nil;
21 | }
22 | @end
--------------------------------------------------------------------------------
/JLRubyChina/Common/RCAPIClient.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCAPIClient.h
3 | // SinaMBlogNimbus
4 | //
5 | // Created by jimneylee on 13-7-25.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLAFAPIBaseClient.h"
10 |
11 | /* RubyChina
12 | GET ruby-china.org/api/topics.json
13 | GET ruby-china.org/api/topics/node/:id.json
14 | POST ruby-china.org/api/topics.json
15 | GET ruby-china.org/api/topics/:id.json
16 | POST ruby-china.org/api/topics/:id/replies.json
17 | GET ruby-china.org/api/nodes.json
18 | GET ruby-china.org/api/sites.json
19 | PUT ruby-china.org/api/user/favorite/:user/:topic.json
20 | GET ruby-china.org/api/users.json
21 | GET ruby-china.org/api/users/:user.json
22 | GET ruby-china.org/api/users/:user/topics.json
23 | GET ruby-china.org/api/users/:user/topics/favorite.json
24 | POST ruby-china.org/api/topics/:id/follow.json
25 | POST ruby-china.org/api/topics/:id/unfollow.json
26 | POST ruby-china.org/api/topics/:id/favorite.json
27 | GET ruby-china.org/api/users/temp_access_token.json
28 | */
29 |
30 | /* V2EX
31 | ('/api/site/stats.json', SiteStatsHandler),
32 | ('/api/site/info.json', SiteInfoHandler),
33 | ('/api/nodes/all.json', NodesAllHandler),
34 | ('/api/nodes/show.json', NodesShowHandler),
35 | ('/api/topics/latest.json', TopicsLatestHandler),
36 | ('/api/topics/show.json', TopicsShowHandler),
37 | ('/api/topics/create.json', TopicsCreateHandler),
38 | ('/api/replies/show.json', RepliesShowHandler),
39 | ('/api/members/show.json', MembersShowHandler),
40 | ('/api/currency.json', CurrencyHandler)
41 | */
42 |
43 | @interface RCAPIClient : JLAFAPIBaseClient
44 |
45 | + (RCAPIClient*)sharedClient;
46 |
47 | //================================================================================
48 | // account sing in
49 | //================================================================================
50 |
51 | // 登录
52 | + (NSString*)relativePathForSignIn;
53 |
54 | //================================================================================
55 | // topic read
56 | //================================================================================
57 |
58 | // 热帖
59 | + (NSString*)relativePathForTopicsWithPageIndex:(unsigned int)pageIndex
60 | pageSize:(unsigned int)pageSize;
61 |
62 | // 查看帖子详细 TODO:评论没有按实现先后排序,有错乱
63 | + (NSString*)relativePathForTopicDetailWithTopicId:(unsigned long)topicId;
64 |
65 | // 帖子回复列表
66 | + (NSString*)relativePathForTopicRepliesWithTopicId:(unsigned long)topicId
67 | pageIndex:(unsigned int)pageIndex
68 | pageSize:(unsigned int)pageSize;
69 |
70 | // 节点帖子
71 | + (NSString*)relativePathForTopicsWithNodeId:(unsigned int)nodeId
72 | pageIndex:(unsigned int)pageIndex
73 | pageSize:(unsigned int)pageSize;
74 |
75 | // 用户发的帖子列表 TODO:此接口总是返回最新的15条:http://ruby-china.org/api/v2/users/huacnlee/topics.json?page=1&per_page=30
76 | + (NSString*)relativePathForPostedTopicsWithUserLoginId:(NSString*)loginId
77 | pageIndex:(unsigned int)pageIndex
78 | pageSize:(unsigned int)pageSize;
79 |
80 | // 用户收藏帖子列表
81 | + (NSString*)relativePathForFavoritedTopicsWithUserLoginId:(NSString*)loginId
82 | pageIndex:(unsigned int)pageIndex
83 | pageSize:(unsigned int)pageSize;
84 |
85 | // 论坛所有节点
86 | + (NSString*)relativePathForForumNodes;
87 |
88 | // 酷站
89 | + (NSString*)relativePathForCoolSites;
90 |
91 | // TOP会员
92 | + (NSString*)relativePathForTopMembersWithPageIndex:(unsigned int)pageIndex
93 | pageSize:(unsigned int)pageSize;
94 |
95 | //================================================================================
96 | // topic write
97 | //================================================================================
98 |
99 | // 发布新帖
100 | + (NSString*)relativePathForPostNewTopic;
101 |
102 | // 回复帖子
103 | + (NSString*)relativePathForReplyTopicId:(unsigned long)topicId;
104 |
105 | // 收藏帖子
106 | + (NSString*)relativePathForFavoriteTopicId:(unsigned long)topicId;
107 |
108 | // 关注帖子
109 | + (NSString*)relativePathForFollowTopicId:(unsigned long)topicId;
110 |
111 | // 取消关注帖子
112 | + (NSString*)relativePathForUnfollowTopicId:(unsigned long)topicId;
113 |
114 | //================================================================================
115 | // user page
116 | //================================================================================
117 |
118 | // 用户主页
119 | + (NSString*)relativePathForVisitUserHomepageWithLoginId:(NSString*)username;
120 |
121 | @end
122 |
123 | NSString *const kAPIBaseURLString;
--------------------------------------------------------------------------------
/JLRubyChina/Common/RCJSONKeys.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCJSONKeys.h
3 | // RCAPIClient
4 | //
5 | // Created by Lee jimney on 7/31/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #ifndef JLRubyChina_SMJSONKeys_h
10 | #define JLRubyChina_SMJSONKeys_h
11 |
12 | //==========================================================================
13 | // common
14 | #define JSON_ID @"id"
15 | #define JSON_LOGIN @"login"
16 | #define JSON_PRIVATE_TOKEN @"private_token"
17 | #define JSON_AVATAR_URL @"avatar_url"
18 | #define JSON_USER @"user"
19 | #define JSON_TITLE @"title"
20 | #define JSON_CREATEED_AT @"created_at"
21 | #define JSON_UPDATEED_AT @"updated_at"
22 | #define JSON_REPLIED_AT @"replied_at"
23 | #define JSON_REPLIES_COUNT @"replies_count"
24 | #define JSON_NODE_NAME @"node_name"
25 | #define JSON_NODE_ID @"node_id"
26 | #define JSON_LAST_REPLY_USER_ID @"last_reply_user_id"
27 | #define JSON_LAST_REPLY_USER_LOGIN @"last_reply_user_login"
28 | #define JSON_BODY @"body"
29 | #define JSON_BODY_HTML @"body_html"
30 | #define JSON_HITS_COUNT @"hits"
31 | #define JSON_REPLIES_LIST @"replies"
32 | #define JSON_NAME @"name"
33 | #define JSON_TOPICS_LIST @"topics"
34 | #define JSON_TOPICS_COUNT @"topics_count"
35 | #define JSON_SUMMARY @"summary"
36 | #define JSON_SECTION_ID @"section_id"
37 | #define JSON_SECTION_NAME @"section_name"
38 | #define JSON_SORT @"sort"
39 | #define JSON_SITE_SECTION_ID @"_id"
40 | #define JSON_SITES_LIST @"sites"
41 | #define JSON_DESCRIPTION @"desc"
42 | #define JSON_FAV_ICON @"favicon"
43 | #define JSON_URL @"url"
44 |
45 | // addition for V2EX
46 | #define JSON_USERNAME @"username"
47 | #define JSON_NODE @"node"
48 | #define JSON_MEMBER @"member"
49 | #define JSON_TAGLINE @"tagline"
50 | #define JSON_AVATAR_MINI @"avatar_mini"
51 | #define JSON_CONTENT @"content"
52 | #define JSON_REPLIES @"replies"
53 | #define JSON_CREATED @"created"
54 | #define JSON_LAST_MODIFIED @"last_modified"
55 | #define JSON_TOPICS @"topics"
56 | #define JSON_HEADER @"header"
57 | #define JSON_FOOTER @"footer"
58 |
59 | #endif
60 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCAboutAppC.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCAboutAppC.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/14/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class NIAttributedLabel;
12 | @interface RCAboutAppC : UIViewController
13 |
14 | @property (nonatomic, strong) IBOutlet NIAttributedLabel* nameLabel;
15 | @property (nonatomic, strong) IBOutlet NIAttributedLabel* siteUrlLabel;
16 | @property (nonatomic, strong) IBOutlet UITextView* siteIntroduceTextView;
17 | @property (nonatomic, strong) IBOutlet NIAttributedLabel* devIntroduceLabel;
18 | @property (nonatomic, strong) IBOutlet NIAttributedLabel* versionLabel;
19 |
20 | - (instancetype)initWithCreateLauchImage:(BOOL)toCreateLauchImage;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCContentPhotoBrowerC.h:
--------------------------------------------------------------------------------
1 | //
2 | // SNPhotoBrowerC.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-10-21.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RCContentPhotoBrowerC : UIViewController
12 |
13 | - (id)initWithPhotoUrls:(NSArray*)photos;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCCoolSitesC.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCCoolSitesC.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-12.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RCCoolSitesC : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCForumNodesC.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCForumNodesC.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-11.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusTableViewController.h"
10 |
11 | @interface RCForumNodesC : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCForumTopicsC.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCForumTopicsC.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusTableViewController.h"
10 |
11 | @interface RCForumTopicsC : JLNimbusTableViewController
12 |
13 | // 根据类型初始化,无其他参数:热门帖子、精华帖等
14 | - (id)initWithTopicsType:(RCForumTopicsType)topicsType;
15 |
16 | // 分类节点帖子列表
17 | - (id)initWithNodeName:(NSString*)nodeName nodeId:(NSUInteger)nodeId;
18 |
19 | // 用户的帖子列表
20 | - (id)initWithUserLoginId:(NSString*)loginId;
21 |
22 | // 用户收藏的帖子列表
23 | - (id)initForFavoritedWithUserLoginId:(NSString*)loginId;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCLeftMenuC.h:
--------------------------------------------------------------------------------
1 | //
2 | // LeftViewController.h
3 | // EasySample
4 | //
5 | // Created by Marian PAUL on 12/06/12.
6 | // Copyright (c) 2012 Marian PAUL aka ipodishima — iPuP SARL. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef enum
12 | {
13 | LeftMenuType_Home=0,
14 | LeftMenuType_ForumNodes,
15 | LeftMenuType_CoolSites,
16 | LeftMenuType_TopMembers,
17 | LeftMenuType_MyHomePage,
18 | LeftMenuType_Wiki,
19 | LeftMenuType_More
20 | }LeftMenuType;
21 |
22 | @protocol RCLeftMenuDelegate;
23 | @interface RCLeftMenuC : UIViewController
24 |
25 | @property (assign, nonatomic) id delegate;
26 |
27 | - (id)initWithStyle:(UITableViewStyle)style;
28 | - (void)setSelectedMenuType:(LeftMenuType)type;
29 |
30 | @end
31 |
32 | @protocol RCLeftMenuDelegate
33 |
34 | - (void)didSelectLeftMenuType:(LeftMenuType)type;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCLoginC.h:
--------------------------------------------------------------------------------
1 | //
2 | // SNLoginC.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-7-25.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RCLoginC : UITableViewController
12 |
13 | @end
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCMoreC.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCMoreC.h
3 | // RubyChina
4 | //
5 | // Created by Lee jimney on 10/7/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RCMoreC : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCNodesCloudTagC.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCForumNodesCloudTagC.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-13.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCNodeEntity.h"
10 |
11 | @protocol RCNodesCloudTagDelegate;
12 | @interface RCNodesCloudTagC : UIViewController
13 | @property (nonatomic, assign) iddelegate;
14 | @end
15 |
16 | @protocol RCNodesCloudTagDelegate
17 |
18 | @optional
19 | - (void)didSelectANode:(RCNodeEntity*)nodeEntity;
20 |
21 | @end
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCNodesCloudTagC.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCForumNodesCloudTagC.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-13.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCNodesCloudTagC.h"
10 | #import "RCForumNodesModel.h"
11 | #import "RCNodeEntity.h"
12 | #import "RTagCloudView.h"
13 |
14 | @interface RCNodesCloudTagC ()
15 | @property (nonatomic, strong) RTagCloudView* tagCloudView;
16 | @property (nonatomic, strong) RCForumNodesModel* model;
17 | @property (nonatomic, strong) NSArray* nodesArray;
18 | @end
19 |
20 | @implementation RCNodesCloudTagC
21 |
22 | ///////////////////////////////////////////////////////////////////////////////////////////////////
23 | ///////////////////////////////////////////////////////////////////////////////////////////////////
24 | #pragma mark - UIViewController
25 |
26 | ///////////////////////////////////////////////////////////////////////////////////////////////////
27 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
28 | {
29 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
30 | if (self) {
31 | // Custom initialization
32 | self.model = [[RCForumNodesModel alloc] init];
33 | self.title = @"请选择分类";
34 | }
35 | return self;
36 | }
37 |
38 | ///////////////////////////////////////////////////////////////////////////////////////////////////
39 | - (void)viewDidLoad
40 | {
41 | [super viewDidLoad];
42 |
43 | [self.model loadNodesWithBlock:^(NSArray *nodeSectionsArray, NSError *error) {
44 | self.nodesArray = self.model.nodesArray;
45 | self.tagCloudView = self.tagCloudView;
46 | }];
47 | }
48 |
49 | ///////////////////////////////////////////////////////////////////////////////////////////////////
50 | - (void)didReceiveMemoryWarning
51 | {
52 | [super didReceiveMemoryWarning];
53 | // Dispose of any resources that can be recreated.
54 | }
55 |
56 | ///////////////////////////////////////////////////////////////////////////////////////////////////
57 | - (void)viewWillDisappear:(BOOL)animated
58 | {
59 | [super viewWillDisappear:animated];
60 | if (self.model.isLoading) {
61 | [self.model cancelRequstOperation];
62 | }
63 | }
64 |
65 | ///////////////////////////////////////////////////////////////////////////////////////////////////
66 | ///////////////////////////////////////////////////////////////////////////////////////////////////
67 | #pragma mark - Private
68 |
69 | ///////////////////////////////////////////////////////////////////////////////////////////////////
70 | - (RTagCloudView*)tagCloudView
71 | {
72 | if (!_tagCloudView) {
73 | _tagCloudView = [[RTagCloudView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, self.view.height)];
74 | _tagCloudView.backgroundColor = TABLE_VIEW_BG_COLOR;
75 | _tagCloudView.center = CGPointMake(self.view.width /2, self.view.height / 2);
76 | _tagCloudView.dataSource = self;
77 | _tagCloudView.delegate = self;
78 | [self.view addSubview:_tagCloudView];
79 | }
80 | return _tagCloudView;
81 | }
82 |
83 | ///////////////////////////////////////////////////////////////////////////////////////////////////
84 | ///////////////////////////////////////////////////////////////////////////////////////////////////
85 | #pragma mark - RTagCloudViewDatasource
86 |
87 | ///////////////////////////////////////////////////////////////////////////////////////////////////
88 | - (NSInteger)numberOfTags:(RTagCloudView *)tagCloud
89 | {
90 | return self.nodesArray.count;
91 | }
92 |
93 | ///////////////////////////////////////////////////////////////////////////////////////////////////
94 | - (NSString*)RTagCloudView:(RTagCloudView *)tagCloud
95 | tagNameOfIndex:(NSInteger)index
96 | {
97 | if (index < self.nodesArray.count) {
98 | RCNodeEntity* node = self.nodesArray[index];
99 | return node.nodeName;
100 | }
101 | return @"未知分类";
102 | }
103 |
104 | ///////////////////////////////////////////////////////////////////////////////////////////////////
105 | - (UIFont*)RTagCloudView:(RTagCloudView *)tagCloud
106 | tagFontOfIndex:(NSInteger)index
107 | {
108 | CGFloat fontSize = 14.f;
109 | if (index < self.nodesArray.count) {
110 | RCNodeEntity* node = self.nodesArray[index];
111 | if (node.topicsCount > 2500) {
112 | fontSize = 30.f;
113 | }
114 | else if (node.topicsCount > 2000) {
115 | fontSize = 28.f;
116 | }
117 | else if (node.topicsCount > 1500) {
118 | fontSize = 26.f;
119 | }
120 | else if (node.topicsCount > 1000) {
121 | fontSize = 24.f;
122 | }
123 | else if (node.topicsCount > 500) {
124 | fontSize = 22.f;
125 | }
126 | else if (node.topicsCount > 200) {
127 | fontSize = 20.f;
128 | }
129 | else if (node.topicsCount > 100) {
130 | fontSize = 18.f;
131 | }
132 | else if (node.topicsCount > 50) {
133 | fontSize = 16.f;
134 | }
135 | else {
136 | fontSize = 14.f;
137 | }
138 | }
139 | return [UIFont systemFontOfSize:fontSize];
140 | }
141 |
142 | ///////////////////////////////////////////////////////////////////////////////////////////////////
143 | - (UIColor*)RTagCloudView:(RTagCloudView *)tagCloud tagColorOfIndex:(NSInteger)index
144 | {
145 | UIColor *colors[] = {
146 | [UIColor redColor],
147 | [UIColor yellowColor],
148 | [UIColor blueColor],
149 | [UIColor orangeColor],
150 | [UIColor blackColor],
151 | [UIColor purpleColor],
152 | [UIColor greenColor]
153 | };
154 | return colors[index%7];
155 | }
156 |
157 | ///////////////////////////////////////////////////////////////////////////////////////////////////
158 | ///////////////////////////////////////////////////////////////////////////////////////////////////
159 | #pragma mark - RTagCloudViewDelegate
160 |
161 | ///////////////////////////////////////////////////////////////////////////////////////////////////
162 | - (void)RTagCloudView:(RTagCloudView*)tagCloud didTapOnTagOfIndex:(NSInteger)index
163 | {
164 | if (index < self.nodesArray.count) {
165 | RCNodeEntity* node = self.nodesArray[index];
166 | self.title = [NSString stringWithFormat:@"已选择 %@", node.nodeName];
167 | if ([self.delegate respondsToSelector:@selector(didSelectANode:)]) {
168 | [self.delegate didSelectANode:node];
169 | }
170 | }
171 | }
172 |
173 | @end
174 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCPostC.h:
--------------------------------------------------------------------------------
1 | //
2 | // SNPostC.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-9-9.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol RCPostDelegate;
12 |
13 | // TODO:当前采用tableview实现,除了键盘弹出好处理,其他太过复杂,后面考虑简单化
14 | @interface RCPostC : UITableViewController
15 |
16 | @property (nonatomic, assign) id postDelegate;
17 |
18 | @end
19 |
20 | @protocol RCPostDelegate
21 |
22 | - (void)didPostNewTopic;
23 |
24 | @end
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCQuickReplyC.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCQuickReplyC.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/12/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "HPGrowingTextView.h"
11 | #import "TSEmojiView.h"
12 | #import "RCReplyEntity.h"
13 |
14 | @protocol RCQuickReplyDelegate;
15 | @interface RCQuickReplyC : UIViewController
16 |
17 | @property(nonatomic, strong) HPGrowingTextView *textView;
18 | @property (nonatomic, strong) TSEmojiView* emojiView;
19 | @property (nonatomic, assign) id replyDelegate;
20 |
21 | - (id)initWithTopicId:(unsigned long)topicId;
22 | - (void)appendString:(NSString*)string;
23 |
24 | @end
25 |
26 | @protocol RCQuickReplyDelegate
27 | @optional
28 | - (void)didReplySuccessWithMyReply:(RCReplyEntity*)replyEntity;
29 | - (void)didReplyFailure;
30 | - (void)didReplyCancel;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCTopMembersC.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopUsersC.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/14/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 | #import "NimbusLauncher.h"
9 | @interface RCTopMembersC : NILauncherViewController
10 |
11 | @end
12 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCTopMembersC_list.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopUsersC.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/14/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusTableViewController.h"
10 |
11 | //TODO: use launch view to show top N, more better
12 | @interface RCTopMembersC : JLNimbusTableViewController
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCTopMembersC_list.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopUsersC.m
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/14/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCTopMembersC.h"
10 | #import "RCUserEntity.h"
11 | #import "RCTopMembersModel.h"
12 |
13 | @interface RCTopMembersC ()
14 |
15 | @end
16 |
17 | @implementation RCTopMembersC
18 |
19 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
20 | {
21 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
22 | if (self) {
23 | // Custom initialization
24 | self.title = @"TOP活跃会员";
25 | self.navigationItem.leftBarButtonItem = [RCGlobalConfig createMenuBarButtonItemWithTarget:self
26 | action:@selector(showLeft:)];
27 | }
28 | return self;
29 | }
30 |
31 | - (void)viewDidLoad
32 | {
33 | [super viewDidLoad];
34 | // Do any additional setup after loading the view.
35 | self.tableView.separatorColor = [UIColor clearColor];
36 | self.tableView.backgroundColor = TABLE_VIEW_BG_COLOR;
37 | self.tableView.backgroundView = nil;
38 | }
39 |
40 | - (void)didReceiveMemoryWarning
41 | {
42 | [super didReceiveMemoryWarning];
43 | // Dispose of any resources that can be recreated.
44 | }
45 |
46 | ///////////////////////////////////////////////////////////////////////////////////////////////////
47 | ///////////////////////////////////////////////////////////////////////////////////////////////////
48 | #pragma mark - Override
49 |
50 | ///////////////////////////////////////////////////////////////////////////////////////////////////
51 | - (id)tableModelClass
52 | {
53 | return [RCTopMembersModel class];
54 | }
55 |
56 | ///////////////////////////////////////////////////////////////////////////////////////////////////
57 | - (NITableViewActionBlock)tapAction
58 | {
59 | return ^BOOL(id object, id target) {
60 | if (!self.editing) {
61 | if ([object isKindOfClass:[RCUserEntity class]]) {
62 | RCUserEntity* o = (RCUserEntity*)object;
63 | [RCGlobalConfig hudShowMessage:o.username addedToView:self.view];
64 | }
65 | return YES;
66 | }
67 | else {
68 | return NO;
69 | }
70 | };
71 | }
72 |
73 | ///////////////////////////////////////////////////////////////////////////////////////////////////
74 | - (void)showMessageForEmpty
75 | {
76 | NSString* msg = @"信息为空";
77 | [RCGlobalConfig hudShowMessage:msg addedToView:self.view];
78 | }
79 |
80 | ///////////////////////////////////////////////////////////////////////////////////////////////////
81 | - (void)showMessageForError
82 | {
83 | NSString* msg = @"抱歉,无法获取信息,请稍后再试!";
84 | [RCGlobalConfig hudShowMessage:msg addedToView:self.view];
85 | }
86 |
87 | ///////////////////////////////////////////////////////////////////////////////////////////////////
88 | - (void)showMssageForLastPage
89 | {
90 | //NSString* msg = @"已是最后一页";
91 | //[RCGlobalConfig hudShowMessage:msg addedToView:self.view];
92 | }
93 |
94 | ///////////////////////////////////////////////////////////////////////////////////////////////////
95 | ///////////////////////////////////////////////////////////////////////////////////////////////////
96 | #pragma mark Side View Controller
97 |
98 | ///////////////////////////////////////////////////////////////////////////////////////////////////
99 | - (void)showLeft:(id)sender
100 | {
101 | // used to push a new controller, but we preloaded it !
102 | [self.revealSideViewController pushOldViewControllerOnDirection:PPRevealSideDirectionLeft
103 | withOffset:SIDE_DIRECTION_LEFT_OFFSET
104 | animated:YES];
105 | }
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCTopicDetailC.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopicDetailC.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusTableViewController.h"
10 |
11 | // TODO:楼层调转
12 | @interface RCTopicDetailC : JLNimbusTableViewController
13 | - (id)initWithTopicId:(unsigned long)topicId;
14 | - (void)replyTopicWithFloorAtSomeone:(NSString*)floorAtsomeoneString;
15 | @end
16 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCUserHomepageC.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopicDetailC.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusTableViewController.h"
10 |
11 | @interface RCUserHomepageC : JLNimbusTableViewController
12 |
13 | // only me in left side, my home homepage
14 | - (id)initWithMyLoginId:(NSString*)loginId;
15 |
16 | // for anyone include me, can back to privious controller
17 | - (id)initWithUserLoginId:(NSString*)loginId;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCWikiC.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCWikiC.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/14/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "NIWebController.h"
10 |
11 | // TODO: 很奇怪,基于Ruby on rails后台web请求有时不被响应,
12 | // 如:进入wiki页面后,点击一条wiki,webview的delegate没有调用
13 | // - (void)webViewDidStartLoad:(UIWebView*)webView
14 | // 导致底部前进和后退无法操作,疑问是
15 | // 后台处理页面请求方式与php、js等是不是不太一样,小白,待求解
16 | @interface RCWikiC : NIWebController
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/JLRubyChina/Controller/RCWikiC.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCWikiC.m
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/14/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCWikiC.h"
10 |
11 | @interface RCWikiC ()
12 |
13 | @end
14 |
15 | @implementation RCWikiC
16 |
17 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
18 | {
19 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
20 | if (self) {
21 | // Custom initialization
22 | self.title = @"Wiki";
23 | }
24 | return self;
25 | }
26 |
27 | - (void)viewDidLoad
28 | {
29 | [super viewDidLoad];
30 | // Do any additional setup after loading the view.
31 | }
32 |
33 | - (void)didReceiveMemoryWarning
34 | {
35 | [super didReceiveMemoryWarning];
36 | // Dispose of any resources that can be recreated.
37 | }
38 |
39 | - (void)viewWillAppear:(BOOL)animated
40 | {
41 | [super viewWillAppear:animated];
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCAccountEntity.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCUserEntity.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusEntity.h"
10 |
11 | @interface RCAccountEntity : JLNimbusEntity
12 | @property (nonatomic, copy) NSString* loginId;// 用户注册时,用户自己输入的ID号,api接口均使用这个id
13 | @property (nonatomic, copy) NSString* privateToken;
14 |
15 | + (RCAccountEntity*)loadStoredUserAccount;
16 |
17 | + (void)storePrivateToken:(NSString*)privateToken forLoginId:(NSString*)loginId;
18 | + (void)deleteLoginedUserDiskData;
19 |
20 | + (void)storeLoginId:(NSString*)loginId;
21 | + (NSString*)readLoginId;
22 | + (void)deleteLoginId;
23 |
24 | + (NSString*)readPrivateToken;
25 | + (void)deletePrivateToken;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCAccountEntity.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCAccountEntity.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCAccountEntity.h"
10 | #import "SSKeychain.h"
11 |
12 | NSString* kRubyChinaService = @"RubyChinaService";
13 | NSString* kLoginId = @"LoginId";
14 |
15 | //{
16 | // avatar = {
17 | // big = {
18 | // url = "https://ruby-china-files.b0.upaiyun.com/user/big_avatar/4988.jpg";
19 | // };
20 | // large = {
21 | // url = "https://ruby-china-files.b0.upaiyun.com/user/large_avatar/4988.jpg";
22 | // };
23 | // normal = {
24 | // url = "https://ruby-china-files.b0.upaiyun.com/user/normal_avatar/4988.jpg";
25 | // };
26 | // small = {
27 | // url = "https://ruby-china-files.b0.upaiyun.com/user/small_avatar/4988.jpg";
28 | // };
29 | // url = "https://ruby-china-files.b0.upaiyun.com/user/avatar/4988.jpg";
30 | // };
31 | // email = "jimneylee@gmail.com";
32 | // login = jimneylee;
33 | // "private_token" = "8a67b1e1042c8093f709:4988";
34 | //}
35 | @implementation RCAccountEntity
36 |
37 | ///////////////////////////////////////////////////////////////////////////////////////////////////
38 | - (id)initWithDictionary:(NSDictionary*)dic
39 | {
40 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
41 | return nil;
42 | }
43 |
44 | self = [super initWithDictionary:dic];
45 | if (self) {
46 | self.loginId = dic[JSON_LOGIN];
47 | self.privateToken = dic[JSON_PRIVATE_TOKEN];
48 | }
49 | return self;
50 | }
51 |
52 | ///////////////////////////////////////////////////////////////////////////////////////////////////
53 | + (id)entityWithDictionary:(NSDictionary*)dic
54 | {
55 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
56 | return nil;
57 | }
58 |
59 | RCAccountEntity* entity = [[RCAccountEntity alloc] initWithDictionary:dic];
60 | return entity;
61 | }
62 |
63 | ///////////////////////////////////////////////////////////////////////////////////////////////////
64 | ///////////////////////////////////////////////////////////////////////////////////////////////////
65 | #pragma mark - Load & Delete logined user
66 |
67 | ///////////////////////////////////////////////////////////////////////////////////////////////////
68 | + (RCAccountEntity*)loadStoredUserAccount
69 | {
70 | NSString* loginId = [RCAccountEntity readLoginId];
71 | NSString* privateToken = [RCAccountEntity readPrivateToken];
72 | if (loginId && privateToken) {
73 | RCAccountEntity* user = [[RCAccountEntity alloc] init];
74 | user.loginId = loginId;
75 | user.privateToken = privateToken;
76 | return user;
77 | }
78 | return nil;
79 | }
80 |
81 | ///////////////////////////////////////////////////////////////////////////////////////////////////
82 | + (void)deleteLoginedUserDiskData
83 | {
84 | [RCAccountEntity deletePrivateToken];
85 | [RCAccountEntity deleteLoginId];
86 | }
87 |
88 | ///////////////////////////////////////////////////////////////////////////////////////////////////
89 | ///////////////////////////////////////////////////////////////////////////////////////////////////
90 | #pragma mark - Store & Read login id
91 | ///////////////////////////////////////////////////////////////////////////////////////////////////
92 | ///////////////////////////////////////////////////////////////////////////////////////////////////
93 | + (void)storeLoginId:(NSString*)loginId
94 | {
95 | [[NSUserDefaults standardUserDefaults] setObject:loginId forKey:kLoginId];
96 | [[NSUserDefaults standardUserDefaults] synchronize];
97 | }
98 |
99 | ///////////////////////////////////////////////////////////////////////////////////////////////////
100 | + (NSString*)readLoginId
101 | {
102 | NSString* LoginedLoginId = [[NSUserDefaults standardUserDefaults] objectForKey:kLoginId];
103 | return LoginedLoginId;
104 | }
105 |
106 | ///////////////////////////////////////////////////////////////////////////////////////////////////
107 | + (void)deleteLoginId
108 | {
109 | [[NSUserDefaults standardUserDefaults] setObject:nil forKey:kLoginId];
110 | [[NSUserDefaults standardUserDefaults] synchronize];
111 | }
112 |
113 | ///////////////////////////////////////////////////////////////////////////////////////////////////
114 | ///////////////////////////////////////////////////////////////////////////////////////////////////
115 | #pragma mark - Store & Read private token
116 |
117 | ///////////////////////////////////////////////////////////////////////////////////////////////////
118 | + (void)storePrivateToken:(NSString*)privateToken forLoginId:(NSString*)loginId
119 | {
120 | NSError *error = nil;
121 | BOOL success = [SSKeychain setPassword:privateToken
122 | forService:kRubyChinaService
123 | account:loginId error:&error];
124 | if (!success || error) {
125 | NSLog(@"can NOT store account");
126 | }
127 | else {
128 | [RCAccountEntity storeLoginId:loginId];
129 | }
130 | }
131 |
132 | ///////////////////////////////////////////////////////////////////////////////////////////////////
133 | + (NSString*)readPrivateToken
134 | {
135 | NSString* LoginedLoginId = [RCAccountEntity readLoginId];
136 | NSString* password = [SSKeychain passwordForService:kRubyChinaService
137 | account:LoginedLoginId];
138 | return password;
139 | }
140 |
141 | ///////////////////////////////////////////////////////////////////////////////////////////////////
142 | + (void)deletePrivateToken
143 | {
144 | NSString* LoginedLoginId = [RCAccountEntity readLoginId];
145 | [SSKeychain deletePasswordForService:kRubyChinaService account:LoginedLoginId];
146 | }
147 |
148 | @end
149 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCKeywordEntity.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCKeywordsEntity.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-11.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RCKeywordEntity : NSObject
12 | @property (nonatomic, copy) NSString* keyword;
13 | @property (nonatomic, assign) NSRange range;
14 | @end
15 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCKeywordEntity.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCKeywordsEntity.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-11.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCKeywordEntity.h"
10 |
11 | @implementation RCKeywordEntity
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCNodeEntity.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCNodeEntity.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-11.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusEntity.h"
10 | //{
11 | // "id": 1,
12 | // "name": "Ruby",
13 | // "topics_count": 1288,
14 | // "summary": "Ruby 鏄竴闂ㄤ紭缇庣殑璇█",
15 | // "section_id": 1,
16 | // "sort": 0,
17 | // "section_name": "Ruby"
18 | //},
19 | @interface RCNodeEntity : JLNimbusEntity
20 | @property (nonatomic, assign) NSUInteger nodeId;
21 | @property (nonatomic, copy) NSString* nodeName;
22 | @property (nonatomic, copy) NSString* summary;
23 | @property (nonatomic, assign) unsigned long topicsCount;
24 | @property (nonatomic, assign) NSUInteger sectionId;
25 | @property (nonatomic, copy) NSString* sectionName;
26 | @end
27 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCNodeEntity.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCNodeEntity.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-11.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCNodeEntity.h"
10 | #import "NSString+stringFromValue.h"
11 |
12 | @implementation RCNodeEntity
13 |
14 | ///////////////////////////////////////////////////////////////////////////////////////////////////
15 | - (id)initWithDictionary:(NSDictionary*)dic
16 | {
17 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
18 | return nil;
19 | }
20 |
21 | self = [super initWithDictionary:dic];
22 | if (self) {
23 | self.nodeId = [dic[JSON_ID] unsignedIntegerValue];
24 |
25 | if (ForumBaseAPIType_RubyChina == FORUM_BASE_API_TYPE) {
26 | self.nodeName = dic[JSON_NAME];
27 | self.topicsCount = [dic[JSON_TOPICS_COUNT] longValue];
28 | self.summary = dic[JSON_SUMMARY];
29 | self.sectionId = [dic[JSON_SECTION_ID] unsignedIntegerValue];
30 | self.sectionName = dic[JSON_SECTION_NAME];
31 | }
32 | else {
33 | self.nodeName = dic[JSON_TITLE];
34 | self.topicsCount = [dic[JSON_TOPICS] longValue];
35 | self.summary = [NSString stringFromValue:dic[JSON_HEADER]];
36 | // TODO: API need add
37 | self.sectionId = 1;
38 | self.sectionName = @"全部暂未分组";
39 | //self.sectionId = [dic[JSON_SECTION_ID] unsignedIntegerValue];
40 | //self.sectionName = dic[JSON_SECTION_NAME];
41 | }
42 | }
43 | return self;
44 | }
45 |
46 | ///////////////////////////////////////////////////////////////////////////////////////////////////
47 | + (id)entityWithDictionary:(NSDictionary*)dic
48 | {
49 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
50 | return nil;
51 | }
52 |
53 | RCNodeEntity* entity = [[RCNodeEntity alloc] initWithDictionary:dic];
54 | return entity;
55 | }
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCNodeSectionEntity.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCNodeSectionEntity.h
3 | // JLRubyChina
4 | //
5 | // Created by Ken_lu on 12/26/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusEntity.h"
10 |
11 | @interface RCNodeSectionEntity : JLNimbusEntity
12 |
13 | @property (nonatomic, assign) NSUInteger sectionId;
14 | @property (nonatomic, copy) NSString* name;
15 | @property (nonatomic, strong) NSMutableArray* nodesArray;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCNodeSectionEntity.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCNodeSectionEntity.m
3 | // JLRubyChina
4 | //
5 | // Created by Ken_lu on 12/26/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCNodeSectionEntity.h"
10 | #import "RCNodeEntity.h"
11 |
12 | @implementation RCNodeSectionEntity
13 |
14 | - (id)init
15 | {
16 | self = [super init];
17 | if (self) {
18 |
19 | }
20 | return self;
21 | }
22 | @end
23 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCReplyEntity.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCReplyEntity.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusEntity.h"
10 | #import "RCUserEntity.h"
11 |
12 | @interface RCReplyEntity : JLNimbusEntity
13 |
14 | @property (nonatomic, strong) RCUserEntity* user;
15 | @property (nonatomic, copy) NSString* replyId;
16 | @property (nonatomic, copy) NSString* body;
17 | @property (nonatomic, strong) NSDate* createdAtDate;
18 | @property (nonatomic, strong) NSDate* updatedAtDate;
19 | @property (nonatomic, assign) NSUInteger floorNumber;
20 | @property (nonatomic, copy) NSString* floorNumberString;
21 | @property (nonatomic, strong) NSArray* atPersonRanges;
22 | @property (nonatomic, strong) NSArray* sharpFloorRanges;
23 | @property (nonatomic, strong) NSArray* emotionRanges;
24 | @property (nonatomic, strong) NSArray* imageUrlsArray;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCReplyEntity.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCReplyEntity.m
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCReplyEntity.h"
10 | #import "NSDate+RubyChina.h"
11 | #import "RCRegularParser.h"
12 | #import "NSString+Emojize.h"
13 |
14 | @implementation RCReplyEntity
15 |
16 | ///////////////////////////////////////////////////////////////////////////////////////////////////
17 | - (id)initWithDictionary:(NSDictionary*)dic
18 | {
19 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
20 | return nil;
21 | }
22 |
23 | self = [super initWithDictionary:dic];
24 | if (self) {
25 | if (ForumBaseAPIType_RubyChina == FORUM_BASE_API_TYPE) {
26 | self.replyId = dic[JSON_ID];
27 | self.body = dic[JSON_BODY];
28 | self.createdAtDate = [NSDate dateFromSourceDateString:dic[JSON_CREATEED_AT]];
29 | self.updatedAtDate = [NSDate dateFromSourceDateString:dic[JSON_UPDATEED_AT]];
30 | self.user = [RCUserEntity entityWithDictionary:dic[JSON_USER]];
31 |
32 | [self parseAllKeywords];
33 | }
34 | else {
35 | self.replyId = dic[JSON_ID];
36 | self.body = dic[JSON_CONTENT];
37 | NSString* createTimestamp = dic[JSON_CREATED];
38 | if (createTimestamp) {
39 | self.createdAtDate = [NSDate dateWithTimeIntervalSince1970:[createTimestamp doubleValue]];
40 | }
41 | self.user = [RCUserEntity entityWithDictionary:dic[JSON_MEMBER]];
42 |
43 | [self parseAllKeywords];
44 | }
45 | }
46 | return self;
47 | }
48 |
49 | ///////////////////////////////////////////////////////////////////////////////////////////////////
50 | + (id)entityWithDictionary:(NSDictionary*)dic
51 | {
52 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
53 | return nil;
54 | }
55 |
56 | RCReplyEntity* entity = [[RCReplyEntity alloc] initWithDictionary:dic];
57 | return entity;
58 | }
59 |
60 | ///////////////////////////////////////////////////////////////////////////////////////////////////
61 | // 识别出 表情 at某人 share话题 标签
62 | - (void)parseAllKeywords
63 | {
64 | if (self.body.length) {
65 | // parse emotion first
66 | self.body = [self.body emojizedString];
67 |
68 | NSString* trimedString = self.body;
69 | self.imageUrlsArray = [RCRegularParser imageUrlsInString:self.body trimedString:&trimedString];
70 | self.body = trimedString;
71 |
72 | if (!self.atPersonRanges) {
73 | self.atPersonRanges = [RCRegularParser keywordRangesOfAtPersonInString:self.body];
74 | }
75 | if (!self.sharpFloorRanges) {
76 | self.sharpFloorRanges = [RCRegularParser keywordRangesOfSharpFloorInString:self.body];
77 | }
78 | }
79 | }
80 |
81 | ///////////////////////////////////////////////////////////////////////////////////////////////////
82 | - (NSString*)floorNumberString
83 | {
84 | if (!_floorNumberString.length) {
85 | NSString* louString = nil;
86 | switch (_floorNumber) {
87 | case 1:
88 | louString = @"沙发";
89 | break;
90 | case 2:
91 | louString = @"板凳";
92 | break;
93 | case 3:
94 | louString = @"地板";
95 | break;
96 | default:
97 | louString = [NSString stringWithFormat:@"%u楼", _floorNumber];
98 | }
99 | _floorNumberString = [louString copy];
100 | }
101 | return _floorNumberString;
102 | }
103 |
104 | ///////////////////////////////////////////////////////////////////////////////////////////////////
105 | // inline sort by reply id, remove it when api return sorted array
106 | - (NSComparisonResult)compare:(RCReplyEntity*)other
107 | {
108 | return [self.replyId compare:other.replyId];
109 | }
110 |
111 | @end
112 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCSiteEntity.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCSiteEntity.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-12.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusEntity.h"
10 |
11 | @interface RCSiteEntity : JLNimbusEntity
12 | @property (nonatomic, copy) NSString* name;
13 | @property (nonatomic, copy) NSString* url;
14 | @property (nonatomic, copy) NSString* iconUrl;
15 | @property (nonatomic, copy) NSString* description;
16 | @end
17 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCSiteEntity.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCSiteEntity.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-12.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCSiteEntity.h"
10 |
11 | @implementation RCSiteEntity
12 |
13 | ///////////////////////////////////////////////////////////////////////////////////////////////////
14 | - (id)initWithDictionary:(NSDictionary*)dic
15 | {
16 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
17 | return nil;
18 | }
19 |
20 | self = [super initWithDictionary:dic];
21 | if (self) {
22 | self.name = dic[JSON_NAME];
23 | self.url = dic[JSON_URL];
24 | self.iconUrl = dic[JSON_FAV_ICON];
25 | self.description = dic[JSON_DESCRIPTION];
26 | }
27 | return self;
28 | }
29 |
30 | ///////////////////////////////////////////////////////////////////////////////////////////////////
31 | + (id)entityWithDictionary:(NSDictionary*)dic
32 | {
33 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
34 | return nil;
35 | }
36 |
37 | RCSiteEntity* entity = [[RCSiteEntity alloc] initWithDictionary:dic];
38 | return entity;
39 | }
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCSiteSectionEntity.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCSiteSectionEntity.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-12.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusEntity.h"
10 |
11 | @interface RCSiteSectionEntity : JLNimbusEntity
12 | @property (nonatomic, assign) NSUInteger sectionId;
13 | @property (nonatomic, copy) NSString* name;
14 | @property (nonatomic, strong) NSArray* sitesArray;
15 | @end
16 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCSiteSectionEntity.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCSiteSectionEntity.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-12.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCSiteSectionEntity.h"
10 | #import "RCSiteEntity.h"
11 |
12 | @implementation RCSiteSectionEntity
13 |
14 | ///////////////////////////////////////////////////////////////////////////////////////////////////
15 | - (id)initWithDictionary:(NSDictionary*)dic
16 | {
17 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
18 | return nil;
19 | }
20 |
21 | self = [super initWithDictionary:dic];
22 | if (self) {
23 | self.sectionId = [dic[JSON_SITE_SECTION_ID] unsignedIntegerValue];
24 | self.name = dic[JSON_NAME];
25 | NSArray* sourceSitesArray = dic[JSON_SITES_LIST];
26 | if (sourceSitesArray.count) {
27 | NSMutableArray* sitesArray = [NSMutableArray arrayWithCapacity:sourceSitesArray.count];
28 | RCSiteEntity* s = nil;
29 | for (NSDictionary* dic in sourceSitesArray) {
30 | s = [RCSiteEntity entityWithDictionary:dic];
31 | [sitesArray addObject:s];
32 | }
33 | self.sitesArray = sitesArray;
34 | }
35 | }
36 | return self;
37 | }
38 |
39 | ///////////////////////////////////////////////////////////////////////////////////////////////////
40 | + (id)entityWithDictionary:(NSDictionary*)dic
41 | {
42 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
43 | return nil;
44 | }
45 |
46 | RCSiteSectionEntity* entity = [[RCSiteSectionEntity alloc] initWithDictionary:dic];
47 | return entity;
48 | }
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCTopicDetailEntity.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopicDetailEntity.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCTopicEntity.h"
10 |
11 | @interface RCTopicDetailEntity : RCTopicEntity
12 |
13 | @property (nonatomic, assign) unsigned long hitsCount;
14 | @property (nonatomic, copy) NSString* body;
15 | @property (nonatomic, copy) NSString* bodyHTML;
16 | @property (nonatomic, copy) NSAttributedString* attributedBody;
17 | @property (nonatomic, strong) NSArray* atPersonRanges;
18 | @property (nonatomic, strong) NSArray* sharpFloorRanges;
19 | @property (nonatomic, strong) NSArray* emotionRanges;
20 | @property (nonatomic, strong) NSArray* imageUrlsArray;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCTopicDetailEntity.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopicDetailEntity.m
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCTopicDetailEntity.h"
10 | #import "RCRegularParser.h"
11 | #import "NSString+Emojize.h"
12 |
13 | #define CONTENT_FONT_SIZE [UIFont fontWithName:@"STHeitiSC-Light" size:18.f]
14 |
15 | @implementation RCTopicDetailEntity
16 |
17 | ///////////////////////////////////////////////////////////////////////////////////////////////////
18 | - (id)initWithDictionary:(NSDictionary*)dic
19 | {
20 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
21 | return nil;
22 | }
23 |
24 | self = [super initWithDictionary:dic];
25 | if (self) {
26 | if (ForumBaseAPIType_RubyChina == FORUM_BASE_API_TYPE) {
27 | self.body = dic[JSON_BODY];
28 |
29 | // 需要注意的是第一行需要指明编码格式 否则的话 中文会显示乱码
30 | // http://hufeng825.github.io/2014/01/21/ios37/
31 | self.bodyHTML = [NSString stringWithFormat:@"%@", dic[JSON_BODY_HTML]];
32 | self.hitsCount = [dic[JSON_HITS_COUNT] unsignedLongValue];
33 | // [self parseAllKeywords];
34 |
35 | // learn from here http://initwithfunk.com/blog/2013/09/29/easy-markdown-rendering-with-nsattributedstring-on-ios-7/
36 | NSDictionary *options = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
37 |
38 | NSMutableAttributedString *mAttributedString = [[NSMutableAttributedString alloc] initWithData:[self.bodyHTML dataUsingEncoding:NSUTF8StringEncoding]
39 | options:options documentAttributes:nil error:nil];
40 | // set line height
41 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
42 | NSDictionary *defaultAttributes = @{NSFontAttributeName : CONTENT_FONT_SIZE};
43 |
44 | paragraphStyle.minimumLineHeight = 21.f;
45 | [mAttributedString addAttribute:NSParagraphStyleAttributeName
46 | value:paragraphStyle
47 | range:NSMakeRange(0, mAttributedString.length)];
48 | [mAttributedString addAttributes:defaultAttributes
49 | range:NSMakeRange(0, mAttributedString.length)];
50 | self.attributedBody = mAttributedString;
51 | }
52 | else {
53 | self.body = dic[JSON_CONTENT];
54 | self.attributedBody = [[NSAttributedString alloc] initWithString:self.body];
55 | [self parseAllKeywords];
56 | }
57 | }
58 | return self;
59 | }
60 |
61 | ///////////////////////////////////////////////////////////////////////////////////////////////////
62 | + (id)entityWithDictionary:(NSDictionary*)dic
63 | {
64 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
65 | return nil;
66 | }
67 |
68 | RCTopicDetailEntity* entity = [[RCTopicDetailEntity alloc] initWithDictionary:dic];
69 | return entity;
70 | }
71 |
72 | ///////////////////////////////////////////////////////////////////////////////////////////////////
73 | // 识别出 表情 at某人 share话题 标签
74 | - (void)parseAllKeywords
75 | {
76 | if (self.body.length) {
77 | // parse emotion first
78 | self.body = [self.body emojizedString];
79 |
80 | NSString* trimedString = self.body;
81 | self.imageUrlsArray = [RCRegularParser imageUrlsInString:self.body trimedString:&trimedString];
82 | self.body = trimedString;
83 |
84 | if (!self.atPersonRanges) {
85 | self.atPersonRanges = [RCRegularParser keywordRangesOfAtPersonInString:self.body];
86 | }
87 | if (!self.sharpFloorRanges) {
88 | self.sharpFloorRanges = [RCRegularParser keywordRangesOfSharpFloorInString:self.body];
89 | }
90 | }
91 | }
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCTopicEntity.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopicEntity.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusEntity.h"
10 | #import "RCUserEntity.h"
11 |
12 | @interface RCTopicEntity : JLNimbusEntity
13 |
14 | @property (nonatomic, strong) RCUserEntity* user;
15 | @property (nonatomic, assign) unsigned long topicId;
16 | @property (nonatomic, copy) NSString* topicTitle;
17 | @property (nonatomic, assign) NSUInteger nodeId;
18 | @property (nonatomic, copy) NSString* nodeName;
19 | @property (nonatomic, strong) NSDate* createdAtDate;
20 | @property (nonatomic, strong) NSDate* updatedAtDate;
21 | @property (nonatomic, strong) NSDate* repliedAtDate;
22 | @property (nonatomic, assign) unsigned long repliesCount;
23 | @property (nonatomic, strong) RCUserEntity* lastRepliedUser;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCTopicEntity.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopicEntity.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCTopicEntity.h"
10 | #import "NSDate+RubyChina.h"
11 | #import "RCNodeEntity.h"
12 |
13 | @implementation RCTopicEntity
14 |
15 | ///////////////////////////////////////////////////////////////////////////////////////////////////
16 | - (id)initWithDictionary:(NSDictionary*)dic
17 | {
18 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
19 | return nil;
20 | }
21 |
22 | self = [super initWithDictionary:dic];
23 | if (self) {
24 |
25 | self.topicId = [dic[JSON_ID] unsignedLongValue];
26 | self.topicTitle = dic[JSON_TITLE];
27 |
28 | if (ForumBaseAPIType_RubyChina == FORUM_BASE_API_TYPE) {
29 | self.nodeId = [dic[JSON_NODE_ID] unsignedIntegerValue];
30 | self.nodeName = dic[JSON_NODE_NAME];
31 | self.createdAtDate = [NSDate dateFromSourceDateString:dic[JSON_CREATEED_AT]];
32 | self.updatedAtDate = [NSDate dateFromSourceDateString:dic[JSON_UPDATEED_AT]];
33 | self.repliedAtDate = [NSDate dateFromSourceDateString:dic[JSON_REPLIED_AT]];
34 | self.repliesCount = [dic[JSON_REPLIES_COUNT] unsignedLongValue];
35 | self.user = [RCUserEntity entityWithDictionary:dic[JSON_USER]];
36 |
37 | NSString* lastRepliedUserLoginId = dic[JSON_LAST_REPLY_USER_LOGIN];
38 | if (lastRepliedUserLoginId && [lastRepliedUserLoginId isKindOfClass:[NSString class]] && lastRepliedUserLoginId.length) {
39 | self.lastRepliedUser = [[RCUserEntity alloc] init];
40 | self.lastRepliedUser.hashId = [dic[JSON_LAST_REPLY_USER_ID] unsignedLongValue];
41 | self.lastRepliedUser.loginId = lastRepliedUserLoginId;
42 | }
43 | }
44 | else {
45 | RCNodeEntity* node = [RCNodeEntity entityWithDictionary:dic[JSON_NODE]];
46 | self.nodeId = node.nodeId;
47 | self.nodeName = node.nodeName;
48 | NSString* createTimestamp = dic[JSON_CREATED];
49 | if (createTimestamp) {
50 | self.createdAtDate = [NSDate dateWithTimeIntervalSince1970:[createTimestamp doubleValue]];
51 | }
52 | self.repliesCount = [dic[JSON_REPLIES] unsignedLongValue];
53 | self.user = [RCUserEntity entityWithDictionary:dic[JSON_MEMBER]];
54 |
55 | //TODO: for v2ex no replied user info
56 | }
57 | }
58 | return self;
59 | }
60 |
61 | ///////////////////////////////////////////////////////////////////////////////////////////////////
62 | + (id)entityWithDictionary:(NSDictionary*)dic
63 | {
64 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
65 | return nil;
66 | }
67 |
68 | RCTopicEntity* entity = [[RCTopicEntity alloc] initWithDictionary:dic];
69 | return entity;
70 | }
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCUserEntity.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCUserEntity.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusEntity.h"
10 |
11 | @interface RCUserEntity : JLNimbusEntity
12 | @property (nonatomic, assign) unsigned long hashId;//注册后,服务器后台自动分配的hash值
13 | @property (nonatomic, copy) NSString* loginId;// 用户注册时,用户自己输入的ID号,api接口均使用这个id
14 | @property (nonatomic, copy) NSString* avatarUrl;
15 | @end
16 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCUserEntity.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCUserEntity.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCUserEntity.h"
10 |
11 | //"user":
12 | //{
13 | //"id": 2596,
14 | //"login": "fengzhilian818",
15 | //"avatar_url": "http://ruby-china.org/avatar/e351cfb6c0fa7e761e5287952f292a16.png?s=120"
16 | //}
17 | @implementation RCUserEntity
18 |
19 | ///////////////////////////////////////////////////////////////////////////////////////////////////
20 | - (id)initWithDictionary:(NSDictionary*)dic
21 | {
22 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
23 | return nil;
24 | }
25 |
26 | self = [super initWithDictionary:dic];
27 | if (self) {
28 | if (ForumBaseAPIType_RubyChina == FORUM_BASE_API_TYPE) {
29 | self.hashId = [dic[JSON_ID] unsignedLongValue];
30 | self.loginId = dic[JSON_LOGIN];
31 | self.avatarUrl = dic[JSON_AVATAR_URL];
32 |
33 | if (![self.avatarUrl hasPrefix:@"http"]) {
34 | self.avatarUrl = [NSString stringWithFormat:@"%@%@", HOST_URL, self.avatarUrl];
35 | }
36 | }
37 | else {
38 | self.hashId = [dic[JSON_ID] unsignedLongValue];
39 | self.loginId = dic[JSON_USERNAME];
40 | self.avatarUrl = dic[JSON_AVATAR_MINI];
41 | }
42 | }
43 | return self;
44 | }
45 |
46 | ///////////////////////////////////////////////////////////////////////////////////////////////////
47 | + (id)entityWithDictionary:(NSDictionary*)dic
48 | {
49 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
50 | return nil;
51 | }
52 |
53 | RCUserEntity* entity = [[RCUserEntity alloc] initWithDictionary:dic];
54 | return entity;
55 | }
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCUserFullEntity.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCUserEntity.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCUserEntity.h"
10 |
11 | @interface RCUserFullEntity : RCUserEntity
12 | @property (nonatomic, copy) NSString* name;
13 | @property (nonatomic, copy) NSString* location;
14 | @property (nonatomic, copy) NSString* company;
15 | @property (nonatomic, copy) NSString* twitter;
16 | @property (nonatomic, copy) NSString* website;
17 | @property (nonatomic, copy) NSString* introduce;
18 | @property (nonatomic, copy) NSString* tagline;
19 | @property (nonatomic, copy) NSString* githubUrl;
20 | @property (nonatomic, copy) NSString* email;
21 | @end
22 |
--------------------------------------------------------------------------------
/JLRubyChina/Entities/RCUserFullEntity.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCUserEntity.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCUserFullEntity.h"
10 | #import "NSString+stringFromValue.h"
11 |
12 | //"user":
13 | //"location": "鍖椾含",
14 | //"company": "",
15 | //"twitter": "chloerei",
16 | //"website": "http://chloerei.com",
17 | //"bio": "Twitter @chloerei\r\n\r\n鎴戝啓浜嗚繖浜涚綉绔欙細\r\n\r\nhttp://writings.io\r\nhttp://codecampo.com ",
18 | //"tagline": "涓笅姘村钩 Rails 绋嬪簭鍛�",
19 | //"github_url": "https://github.com/chloerei",
20 | //"email": "chloerei@gmail.com",
21 | //"gravatar_hash": "5aec84cd0b5479a0d1d89b6ffa2a9a20",
22 | //"avatar_url": "http://ruby-china.org/avatar/5aec84cd0b5479a0d1d89b6ffa2a9a20.png?s=120",
23 | @implementation RCUserFullEntity
24 |
25 | ///////////////////////////////////////////////////////////////////////////////////////////////////
26 | - (id)initWithDictionary:(NSDictionary*)dic
27 | {
28 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
29 | return nil;
30 | }
31 |
32 | self = [super initWithDictionary:dic];
33 | if (self) {
34 | self.name = [NSString stringFromValue:dic[@"name"]];
35 | self.location = [NSString stringFromValue:dic[@"location"]];
36 | self.company = [NSString stringFromValue:dic[@"company"]];
37 | self.twitter = [NSString stringFromValue:dic[@"twitter"]];
38 | self.website = [NSString stringFromValue:dic[@"website"]];
39 | self.introduce = [NSString stringFromValue:dic[@"bio"]];
40 | self.tagline = [NSString stringFromValue:dic[@"tagline"]];
41 | self.githubUrl = [NSString stringFromValue:dic[@"github_url"]];
42 | self.email = [NSString stringFromValue:dic[@"email"]];
43 | }
44 | return self;
45 | }
46 |
47 | ///////////////////////////////////////////////////////////////////////////////////////////////////
48 | + (id)entityWithDictionary:(NSDictionary*)dic
49 | {
50 | if (!dic || ![dic isKindOfClass:[NSDictionary class]]) {
51 | return nil;
52 | }
53 |
54 | RCUserFullEntity* entity = [[RCUserFullEntity alloc] initWithDictionary:dic];
55 | return entity;
56 | }
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/JLRubyChina/JLRubyChina-Dis-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | APP_STORE_ID
6 | 789643801
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleDisplayName
10 | Ruby China
11 | CFBundleExecutable
12 | ${EXECUTABLE_NAME}
13 | CFBundleIcons
14 |
15 | CFBundlePrimaryIcon
16 |
17 | CFBundleIconFiles
18 |
19 | icon
20 | icon58
21 | icon80
22 | icon120
23 |
24 |
25 |
26 | CFBundleIdentifier
27 | cn.rafood.rubychina
28 | CFBundleInfoDictionaryVersion
29 | 6.0
30 | CFBundleName
31 | ${PRODUCT_NAME}
32 | CFBundlePackageType
33 | APPL
34 | CFBundleShortVersionString
35 | 1.3
36 | CFBundleSignature
37 | ????
38 | CFBundleVersion
39 | 1.3
40 | HOST_API_URL
41 | https://ruby-china.org/api/v2/
42 | HOST_BASE_API_TYPE
43 | rubychina
44 | HOST_INTRO
45 | Ruby China,对!没错!这里就是 Ruby 社区,目前这里已经是国内最权威的 Ruby 社区,拥有国内所有资深的 Ruby 工程师。
46 | HOST_URL
47 | https://ruby-china.org
48 | LSRequiresIPhoneOS
49 |
50 | UILaunchImages
51 |
52 |
53 | UILaunchImageMinimumOSVersion
54 | 7.0
55 | UILaunchImageName
56 | Default
57 | UILaunchImageOrientation
58 | Portrait
59 | UILaunchImageSize
60 | {320, 568}
61 |
62 |
63 | UILaunchImageMinimumOSVersion
64 | 7.0
65 | UILaunchImageName
66 | Default-568
67 | UILaunchImageOrientation
68 | Portrait
69 | UILaunchImageSize
70 | {320, 568}
71 |
72 |
73 | UILaunchImageMinimumOSVersion
74 | 7.0
75 | UILaunchImageName
76 | Default-568
77 | UILaunchImageOrientation
78 | Portrait
79 | UILaunchImageSize
80 | {320, 568}
81 |
82 |
83 | UILaunchImageMinimumOSVersion
84 | 7.0
85 | UILaunchImageName
86 | Default-568
87 | UILaunchImageOrientation
88 | Portrait
89 | UILaunchImageSize
90 | {320, 568}
91 |
92 |
93 | UILaunchImageMinimumOSVersion
94 | 7.0
95 | UILaunchImageName
96 | Default
97 | UILaunchImageOrientation
98 | Portrait
99 | UILaunchImageSize
100 | {320, 480}
101 |
102 |
103 | UILaunchImageMinimumOSVersion
104 | 7.0
105 | UILaunchImageName
106 | Default-568
107 | UILaunchImageOrientation
108 | Portrait
109 | UILaunchImageSize
110 | {320, 568}
111 |
112 |
113 | UIRequiredDeviceCapabilities
114 |
115 | armv7
116 |
117 | UISupportedInterfaceOrientations
118 |
119 | UIInterfaceOrientationPortrait
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/JLRubyChina/JLRubyChina-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | APP_STORE_ID
6 | 789643801
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleDisplayName
10 | Ruby China
11 | CFBundleExecutable
12 | ${EXECUTABLE_NAME}
13 | CFBundleIcons
14 |
15 | CFBundlePrimaryIcon
16 |
17 | CFBundleIconFiles
18 |
19 | icon
20 | icon58
21 | icon80
22 | icon120
23 |
24 |
25 |
26 | CFBundleIdentifier
27 | cn.rafood.rubychina
28 | CFBundleInfoDictionaryVersion
29 | 6.0
30 | CFBundleName
31 | ${PRODUCT_NAME}
32 | CFBundlePackageType
33 | APPL
34 | CFBundleShortVersionString
35 | 1.3
36 | CFBundleSignature
37 | ????
38 | CFBundleVersion
39 | 1.3
40 | HOST_API_URL
41 | https://ruby-china.org/api/v2/
42 | HOST_BASE_API_TYPE
43 | rubychina
44 | HOST_INTRO
45 | Ruby China,对!没错!这里就是 Ruby 社区,目前这里已经是国内最权威的 Ruby 社区,拥有国内所有资深的 Ruby 工程师。
46 | HOST_URL
47 | https://ruby-china.org
48 | LSRequiresIPhoneOS
49 |
50 | UILaunchImages
51 |
52 |
53 | UILaunchImageMinimumOSVersion
54 | 7.0
55 | UILaunchImageName
56 | Default
57 | UILaunchImageOrientation
58 | Portrait
59 | UILaunchImageSize
60 | {320, 568}
61 |
62 |
63 | UILaunchImageMinimumOSVersion
64 | 7.0
65 | UILaunchImageName
66 | Default-568
67 | UILaunchImageOrientation
68 | Portrait
69 | UILaunchImageSize
70 | {320, 568}
71 |
72 |
73 | UILaunchImageMinimumOSVersion
74 | 7.0
75 | UILaunchImageName
76 | Default-568
77 | UILaunchImageOrientation
78 | Portrait
79 | UILaunchImageSize
80 | {320, 568}
81 |
82 |
83 | UILaunchImageMinimumOSVersion
84 | 7.0
85 | UILaunchImageName
86 | Default-568
87 | UILaunchImageOrientation
88 | Portrait
89 | UILaunchImageSize
90 | {320, 568}
91 |
92 |
93 | UILaunchImageMinimumOSVersion
94 | 7.0
95 | UILaunchImageName
96 | Default
97 | UILaunchImageOrientation
98 | Portrait
99 | UILaunchImageSize
100 | {320, 480}
101 |
102 |
103 | UILaunchImageMinimumOSVersion
104 | 7.0
105 | UILaunchImageName
106 | Default-568
107 | UILaunchImageOrientation
108 | Portrait
109 | UILaunchImageSize
110 | {320, 568}
111 |
112 |
113 | UIRequiredDeviceCapabilities
114 |
115 | armv7
116 |
117 | UISupportedInterfaceOrientations
118 |
119 | UIInterfaceOrientationPortrait
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/JLRubyChina/JLRubyChina-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_5_0
10 | #warning "This project uses features only available in iOS SDK 5.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | #import
15 | #import
16 |
17 | // Nimbus addtional header
18 | #import "NimbusPagingScrollView.h"
19 |
20 | #import "JLNimbusTimeline.h"
21 | #import "TTCategoryHeader.h"
22 | #import "MBProgressHUD.h"
23 |
24 | #import "RCJSONKeys.h"
25 | #import "RCGlobalConfig.h"
26 | #import "MacroDefines.h"
27 | #import "UIImage+nimbusImageNamed.h"
28 |
29 | #endif
30 |
31 | // debug log switch
32 | #ifdef DEBUG
33 | # define NSLog(...) NSLog(__VA_ARGS__)
34 | #else
35 | # define NSLog(...) {}
36 | #endif
37 |
--------------------------------------------------------------------------------
/JLRubyChina/JLTesterHome-Dis-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | APP_STORE_ID
6 | 803942891
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleDisplayName
10 | Tester Home
11 | CFBundleExecutable
12 | ${EXECUTABLE_NAME}
13 | CFBundleIcons
14 |
15 | CFBundlePrimaryIcon
16 |
17 | CFBundleIconFiles
18 |
19 | icon
20 | icon58
21 | icon80
22 | icon120
23 |
24 |
25 |
26 | CFBundleIdentifier
27 | com.toyaca.testerhome
28 | CFBundleInfoDictionaryVersion
29 | 6.0
30 | CFBundleName
31 | ${PRODUCT_NAME}
32 | CFBundlePackageType
33 | APPL
34 | CFBundleShortVersionString
35 | 1.0
36 | CFBundleSignature
37 | ????
38 | CFBundleVersion
39 | 1.0
40 | LSRequiresIPhoneOS
41 |
42 | UILaunchImages
43 |
44 |
45 | UILaunchImageMinimumOSVersion
46 | 7.0
47 | UILaunchImageName
48 | Default
49 | UILaunchImageOrientation
50 | Portrait
51 | UILaunchImageSize
52 | {320, 568}
53 |
54 |
55 | UILaunchImageMinimumOSVersion
56 | 7.0
57 | UILaunchImageName
58 | Default-568
59 | UILaunchImageOrientation
60 | Portrait
61 | UILaunchImageSize
62 | {320, 568}
63 |
64 |
65 | UILaunchImageMinimumOSVersion
66 | 7.0
67 | UILaunchImageName
68 | Default-568
69 | UILaunchImageOrientation
70 | Portrait
71 | UILaunchImageSize
72 | {320, 568}
73 |
74 |
75 | UILaunchImageMinimumOSVersion
76 | 7.0
77 | UILaunchImageName
78 | Default-568
79 | UILaunchImageOrientation
80 | Portrait
81 | UILaunchImageSize
82 | {320, 568}
83 |
84 |
85 | UILaunchImageMinimumOSVersion
86 | 7.0
87 | UILaunchImageName
88 | Default
89 | UILaunchImageOrientation
90 | Portrait
91 | UILaunchImageSize
92 | {320, 480}
93 |
94 |
95 | UILaunchImageMinimumOSVersion
96 | 7.0
97 | UILaunchImageName
98 | Default-568
99 | UILaunchImageOrientation
100 | Portrait
101 | UILaunchImageSize
102 | {320, 568}
103 |
104 |
105 | UIRequiredDeviceCapabilities
106 |
107 | armv7
108 |
109 | UISupportedInterfaceOrientations
110 |
111 | UIInterfaceOrientationPortrait
112 |
113 | HOST_URL
114 | http://testerhome.com
115 | HOST_API_URL
116 | http://testerhome.com/api/v2/
117 | HOST_INTRO
118 | 国内首个移动测试交流社区,专注于Web测试,移动测试,测试产品与云测服务,一个技术驱动的组织,一个活跃而温馨的测试大家庭。
119 | HOST_BASE_API_TYPE
120 | rubychina
121 | UIViewControllerBasedStatusBarAppearance
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/JLRubyChina/JLTesterHome-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | APP_STORE_ID
6 | 803942891
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleDisplayName
10 | Tester Home
11 | CFBundleExecutable
12 | ${EXECUTABLE_NAME}
13 | CFBundleIcons
14 |
15 | CFBundlePrimaryIcon
16 |
17 | CFBundleIconFiles
18 |
19 | icon
20 | icon58
21 | icon80
22 | icon120
23 |
24 |
25 |
26 | CFBundleIdentifier
27 | com.toyaca.testerhome
28 | CFBundleInfoDictionaryVersion
29 | 6.0
30 | CFBundleName
31 | ${PRODUCT_NAME}
32 | CFBundlePackageType
33 | APPL
34 | CFBundleShortVersionString
35 | 1.0
36 | CFBundleSignature
37 | ????
38 | CFBundleVersion
39 | 1.0
40 | LSRequiresIPhoneOS
41 |
42 | UILaunchImages
43 |
44 |
45 | UILaunchImageMinimumOSVersion
46 | 7.0
47 | UILaunchImageName
48 | Default
49 | UILaunchImageOrientation
50 | Portrait
51 | UILaunchImageSize
52 | {320, 568}
53 |
54 |
55 | UILaunchImageMinimumOSVersion
56 | 7.0
57 | UILaunchImageName
58 | Default-568
59 | UILaunchImageOrientation
60 | Portrait
61 | UILaunchImageSize
62 | {320, 568}
63 |
64 |
65 | UILaunchImageMinimumOSVersion
66 | 7.0
67 | UILaunchImageName
68 | Default-568
69 | UILaunchImageOrientation
70 | Portrait
71 | UILaunchImageSize
72 | {320, 568}
73 |
74 |
75 | UILaunchImageMinimumOSVersion
76 | 7.0
77 | UILaunchImageName
78 | Default-568
79 | UILaunchImageOrientation
80 | Portrait
81 | UILaunchImageSize
82 | {320, 568}
83 |
84 |
85 | UILaunchImageMinimumOSVersion
86 | 7.0
87 | UILaunchImageName
88 | Default
89 | UILaunchImageOrientation
90 | Portrait
91 | UILaunchImageSize
92 | {320, 480}
93 |
94 |
95 | UILaunchImageMinimumOSVersion
96 | 7.0
97 | UILaunchImageName
98 | Default-568
99 | UILaunchImageOrientation
100 | Portrait
101 | UILaunchImageSize
102 | {320, 568}
103 |
104 |
105 | UIRequiredDeviceCapabilities
106 |
107 | armv7
108 |
109 | UISupportedInterfaceOrientations
110 |
111 | UIInterfaceOrientationPortrait
112 |
113 | HOST_URL
114 | http://testerhome.com
115 | HOST_API_URL
116 | http://testerhome.com/api/v2/
117 | HOST_INTRO
118 | 国内首个移动测试交流社区,专注于Web测试,移动测试,测试产品与云测服务,一个技术驱动的组织,一个活跃而温馨的测试大家庭。
119 | HOST_BASE_API_TYPE
120 | rubychina
121 | UIViewControllerBasedStatusBarAppearance
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/JLRubyChina/JLV2EX-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | APP_STORE_ID
6 | 1
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleDisplayName
10 | Livid V2EX
11 | CFBundleExecutable
12 | ${EXECUTABLE_NAME}
13 | CFBundleIcons
14 |
15 | CFBundlePrimaryIcon
16 |
17 | CFBundleIconFiles
18 |
19 | icon
20 | icon58
21 | icon80
22 | icon120
23 |
24 |
25 |
26 | CFBundleIdentifier
27 | cn.rafood.v2ex
28 | CFBundleInfoDictionaryVersion
29 | 6.0
30 | CFBundleName
31 | ${PRODUCT_NAME}
32 | CFBundlePackageType
33 | APPL
34 | CFBundleShortVersionString
35 | 1.0
36 | CFBundleSignature
37 | ????
38 | CFBundleVersion
39 | 1.0
40 | LSRequiresIPhoneOS
41 |
42 | UILaunchImages
43 |
44 |
45 | UILaunchImageMinimumOSVersion
46 | 7.0
47 | UILaunchImageName
48 | Default
49 | UILaunchImageOrientation
50 | Portrait
51 | UILaunchImageSize
52 | {320, 568}
53 |
54 |
55 | UILaunchImageMinimumOSVersion
56 | 7.0
57 | UILaunchImageName
58 | Default-568
59 | UILaunchImageOrientation
60 | Portrait
61 | UILaunchImageSize
62 | {320, 568}
63 |
64 |
65 | UILaunchImageMinimumOSVersion
66 | 7.0
67 | UILaunchImageName
68 | Default-568
69 | UILaunchImageOrientation
70 | Portrait
71 | UILaunchImageSize
72 | {320, 568}
73 |
74 |
75 | UILaunchImageMinimumOSVersion
76 | 7.0
77 | UILaunchImageName
78 | Default-568
79 | UILaunchImageOrientation
80 | Portrait
81 | UILaunchImageSize
82 | {320, 568}
83 |
84 |
85 | UILaunchImageMinimumOSVersion
86 | 7.0
87 | UILaunchImageName
88 | Default
89 | UILaunchImageOrientation
90 | Portrait
91 | UILaunchImageSize
92 | {320, 480}
93 |
94 |
95 | UILaunchImageMinimumOSVersion
96 | 7.0
97 | UILaunchImageName
98 | Default-568
99 | UILaunchImageOrientation
100 | Portrait
101 | UILaunchImageSize
102 | {320, 568}
103 |
104 |
105 | UIRequiredDeviceCapabilities
106 |
107 | armv7
108 |
109 | UISupportedInterfaceOrientations
110 |
111 | UIInterfaceOrientationPortrait
112 |
113 | HOST_URL
114 | http://www.v2ex.com
115 | HOST_API_URL
116 | http://www.v2ex.com/api/
117 | HOST_INTRO
118 | V2EX 是创意工作者们的社区。这里目前汇聚了超过 50000 名主要来自互联网行业、游戏行业和媒体行业的创意工作者。V2EX 希望能够成为创意工作者们的生活和事业的一部分。
119 | HOST_BASE_API_TYPE
120 | v2ex
121 | UIViewControllerBasedStatusBarAppearance
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/JLRubyChina/MacroDefines.h:
--------------------------------------------------------------------------------
1 | //
2 | // MacroDefines.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/16/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #ifndef JLRubyChina_MacroDefines_h
10 | #define JLRubyChina_MacroDefines_h
11 |
12 | // APP 基本信息
13 | #define APP_NAME [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]
14 | #define APP_VERSION [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]
15 | #define APP_ID [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"APP_STORE_ID"] longValue]
16 | #define HOST_URL [[NSBundle mainBundle] objectForInfoDictionaryKey:@"HOST_URL"]
17 | //#define HOST_API_URL [NSString stringWithFormat:@"%@/api/v2", HOST_URL]
18 | #define HOST_API_URL [[NSBundle mainBundle] objectForInfoDictionaryKey:@"HOST_API_URL"]
19 | #define HOST_WIKI_URL [NSString stringWithFormat:@"%@/wiki", HOST_URL]
20 | #define HOST_INTRO [[NSBundle mainBundle] objectForInfoDictionaryKey:@"HOST_INTRO"]
21 | #define FORUM_BASE_API_TYPE [RCGlobalConfig forumBaseAPIType]
22 |
23 | // 是否是iphone5的判断
24 | #define IS_WIDESCREEN ([[UIScreen mainScreen] bounds].size.height > 500)
25 | #define IS_IPHONE ([[[UIDevice currentDevice] model] isEqualToString:@"iPhone"] \
26 | ||[[[UIDevice currentDevice] model] isEqualToString:@"iPhone Simulator"])
27 | #define IS_IPHONE5 (IS_IPHONE && IS_WIDESCREEN)
28 |
29 | // Cell布局
30 | #define CELL_PADDING_10 10
31 | #define CELL_PADDING_8 8
32 | #define CELL_PADDING_6 6
33 | #define CELL_PADDING_4 4
34 | #define CELL_PADDING_2 2
35 |
36 | // Color配色
37 | #define APP_THEME_COLOR RGBCOLOR(41, 41, 41)
38 | #define APP_NAME_RED_COLOR RGBCOLOR(177, 9, 0)
39 | #define APP_NAME_WHITE_COLOR RGBCOLOR(200, 200, 200)
40 | #define TABLE_VIEW_BG_COLOR RGBCOLOR(237, 234, 234)
41 | #define CELL_CONTENT_VIEW_BG_COLOR RGBCOLOR(247, 247, 247)
42 | #define CELL_CONTENT_VIEW_BORDER_COLOR RGBCOLOR(234, 234, 234)
43 |
44 | // 左侧菜单栏可视宽度比
45 | #define LEFT_GAP_PERCENTAGE 0.55f
46 |
47 | // 自定义链接协议
48 | #define PROTOCOL_AT_SOMEONE @"atsomeone://"
49 | #define PROTOCOL_SHARP_FLOOR @"sharpfloor://"
50 | #define PROTOCOL_NODE @"node://"
51 |
52 | // Notification通知
53 | #define DID_LOGIN_NOTIFICATION @"DID_LOGIN_NOTIFICATION"
54 | #define DID_LOGOUT_NOTIFICATION @"DID_LOGOUT_NOTIFICATION"
55 |
56 | #endif
57 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCBaseTableModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // NITimelineTableModel.h
3 | // NimbusTimeline
4 | //
5 | // Created by Lee jimney on 7/27/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "JLNimbusTableModel.h"
10 | #import "RCAPIClient.h"
11 |
12 | @interface RCBaseTableModel : JLNimbusTableModel
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCBaseTableModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // NITimelineTableModel.m
3 | // NimbusTimeline
4 | //
5 | // Created by Lee jimney on 7/27/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCBaseTableModel.h"
10 |
11 | ///////////////////////////////////////////////////////////////////////////////////////////////////
12 | ///////////////////////////////////////////////////////////////////////////////////////////////////
13 | ///////////////////////////////////////////////////////////////////////////////////////////////////
14 | @implementation RCBaseTableModel
15 |
16 | ///////////////////////////////////////////////////////////////////////////////////////////////////
17 | - (id)initWithDelegate:(id)delegate
18 | {
19 | self = [super initWithDelegate:delegate];
20 | if (self)
21 | {
22 | }
23 | return self;
24 | }
25 |
26 | ///////////////////////////////////////////////////////////////////////////////////////////////////
27 | ///////////////////////////////////////////////////////////////////////////////////////////////////
28 | #pragma mark - Override
29 |
30 | ///////////////////////////////////////////////////////////////////////////////////////////////////
31 | - (NSString*)listKey
32 | {
33 | return nil;
34 | }
35 |
36 | ///////////////////////////////////////////////////////////////////////////////////////////////////
37 | ///////////////////////////////////////////////////////////////////////////////////////////////////
38 | #pragma mark - Public
39 |
40 | ///////////////////////////////////////////////////////////////////////////////////////////////////
41 | - (id)apiSharedClient
42 | {
43 | return [RCAPIClient sharedClient];
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCCoolSitesModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCCoolSitesModel.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-12.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | @interface RCCoolSitesModel : NIMutableTableViewModel
10 | @property (nonatomic, strong) NSMutableArray* siteSectionsArray;
11 | @property (nonatomic, assign) BOOL isLoading;
12 | - (Class)objectClass;
13 | - (Class)cellClass;
14 | - (void)loadCoolSitesWithBlock:(void(^)(NSArray* siteSectionsArray, NSError* error))block;
15 | - (void)cancelRequstOperation;
16 | @end
17 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCCoolSitesModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCCoolSitesModel.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-12.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCCoolSitesModel.h"
10 | #import "RCAPIClient.h"
11 | #import "RCSiteSectionEntity.h"
12 | #import "RCSiteEntity.h"
13 | #import "RCSiteCell.h"
14 |
15 | @implementation RCCoolSitesModel
16 |
17 | ///////////////////////////////////////////////////////////////////////////////////////////////////
18 | - (id)initWithDelegate:(id)delegate
19 | {
20 | self = [super initWithDelegate:delegate];
21 | if (self)
22 | {
23 | if (delegate && [delegate isKindOfClass:[NICellFactory class]]) {
24 | NICellFactory* factory = (NICellFactory*)delegate;
25 | NIDASSERT([self objectClass]);
26 | NIDASSERT([self cellClass]);
27 | [factory mapObjectClass:[self objectClass]
28 | toCellClass:[self cellClass]];
29 | }
30 | }
31 | return self;
32 | }
33 |
34 | ///////////////////////////////////////////////////////////////////////////////////////////////////
35 | - (NSString*)relativePath
36 | {
37 | return [RCAPIClient relativePathForCoolSites];//tid = @"111837"
38 | }
39 |
40 | ///////////////////////////////////////////////////////////////////////////////////////////////////
41 | - (Class)objectClass
42 | {
43 | return [RCSiteEntity class];
44 | }
45 |
46 | ///////////////////////////////////////////////////////////////////////////////////////////////////
47 | - (Class)cellClass
48 | {
49 | return [RCSiteCell class];
50 | }
51 |
52 | ///////////////////////////////////////////////////////////////////////////////////////////////////
53 | - (void)loadCoolSitesWithBlock:(void(^)(NSArray* siteSectionsArray, NSError* error))block
54 | {
55 | if (self.isLoading) {
56 | return;
57 | }
58 | else {
59 | self.isLoading = YES;
60 | }
61 | [[RCAPIClient sharedClient] GET:[self relativePath] parameters:nil
62 | success:^(AFHTTPRequestOperation *operation, id responseObject) {
63 | self.isLoading = NO;
64 | if ([responseObject isKindOfClass:[NSArray class]]) {
65 | NSArray* sourceArray = (NSArray*)responseObject;
66 | if (sourceArray.count) {
67 | RCSiteSectionEntity* sectionEntity = nil;
68 | NSMutableArray* siteSectionsArray = [NSMutableArray arrayWithCapacity:sourceArray.count];
69 | for (NSDictionary* dic in sourceArray) {
70 | sectionEntity = [RCSiteSectionEntity entityWithDictionary:dic];
71 | [siteSectionsArray addObject:sectionEntity];
72 | }
73 | self.siteSectionsArray = siteSectionsArray;
74 | if (block) {
75 | block(siteSectionsArray, nil);
76 | return;
77 | }
78 | }
79 | }
80 | if (block) {
81 | NSError* error = [[NSError alloc] init];
82 | block(nil, error);
83 | }
84 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
85 | self.isLoading = NO;
86 | if (block) {
87 | block(nil, error);
88 | }
89 | }];
90 | }
91 |
92 | ///////////////////////////////////////////////////////////////////////////////////////////////////
93 | - (void)cancelRequstOperation
94 | {
95 | if (self.isLoading) {
96 | [[RCAPIClient sharedClient] cancelAllHTTPOperationsWithPath:[self relativePath]];
97 | self.isLoading = NO;
98 | }
99 | }
100 |
101 | @end
102 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCForumNodesModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCForumNodesModel.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-11.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCBaseTableModel.h"
10 |
11 | @interface RCForumNodesModel : NIMutableTableViewModel
12 |
13 | @property (nonatomic, assign) BOOL isLoading;
14 | @property (nonatomic, strong) NSArray* nodesArray;
15 |
16 | @property (nonatomic, strong) NSMutableArray* nodeSectionsArray;
17 | - (Class)objectClass;
18 | - (Class)cellClass;
19 | - (void)loadNodesWithBlock:(void(^)(NSArray* nodeSectionsArray, NSError *error))block;
20 | - (void)cancelRequstOperation;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCForumNodesModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCForumNodesModel.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-11.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCForumNodesModel.h"
10 | #import "RCNodeCell.h"
11 | #import "RCNodeEntity.h"
12 | #import "RCNodeSectionEntity.h"
13 | #import "RCAPIClient.h"
14 |
15 | @implementation RCForumNodesModel
16 |
17 | ///////////////////////////////////////////////////////////////////////////////////////////////////
18 | - (id)initWithDelegate:(id)delegate
19 | {
20 | self = [super initWithDelegate:delegate];
21 | if (self) {
22 | // TODO:数据一次性获取过来,没有分页,这边逻辑有点别扭,待修改
23 | if (delegate && [delegate isKindOfClass:[NICellFactory class]]) {
24 | NICellFactory* factory = (NICellFactory*)delegate;
25 | NIDASSERT([self objectClass]);
26 | NIDASSERT([self cellClass]);
27 | [factory mapObjectClass:[self objectClass]
28 | toCellClass:[self cellClass]];
29 | }
30 | self.nodeSectionsArray = [[NSMutableArray alloc] init];
31 | }
32 | return self;
33 | }
34 |
35 | ///////////////////////////////////////////////////////////////////////////////////////////////////
36 | - (NSString*)relativePath
37 | {
38 | return [RCAPIClient relativePathForForumNodes];
39 | }
40 | ///////////////////////////////////////////////////////////////////////////////////////////////////
41 | - (id)apiSharedClient
42 | {
43 | return [RCAPIClient sharedClient];
44 | }
45 |
46 | ///////////////////////////////////////////////////////////////////////////////////////////////////
47 | - (Class)objectClass
48 | {
49 | return [RCNodeEntity class];
50 | }
51 |
52 | ///////////////////////////////////////////////////////////////////////////////////////////////////
53 | - (Class)cellClass
54 | {
55 | return [RCNodeCell class];
56 | }
57 |
58 | ///////////////////////////////////////////////////////////////////////////////////////////////////
59 | - (NSArray*)entitiesParsedFromResponseObject:(id)responseObject
60 | {
61 | NSArray* sourceArray = (NSArray*)responseObject;
62 | RCNodeEntity* entity = nil;
63 | NSMutableArray* entities = [[NSMutableArray alloc] init];
64 | for (NSDictionary* dic in sourceArray) {
65 | entity = [RCNodeEntity entityWithDictionary:dic];
66 | [entities addObject:entity];
67 | }
68 | self.nodesArray = entities;
69 | for (RCNodeEntity* o in entities) {
70 |
71 | BOOL hasExist = NO;
72 | for (RCNodeSectionEntity* s in _nodeSectionsArray) {
73 | if (s.sectionId == o.sectionId) {
74 | hasExist = YES;
75 | break;
76 | }
77 | }
78 | if (!hasExist) {
79 | RCNodeSectionEntity* s = [[RCNodeSectionEntity alloc] init];
80 | s.sectionId = o.sectionId;
81 | s.name = o.sectionName;
82 | s.nodesArray = [[NSMutableArray alloc] init];
83 | [_nodeSectionsArray addObject:s];
84 | }
85 | }
86 | for (RCNodeEntity* o in entities) {
87 | for (RCNodeSectionEntity* s in _nodeSectionsArray) {
88 | if (s.sectionId == o.sectionId) {
89 | [s.nodesArray addObject:o];
90 | break;
91 | }
92 | }
93 | }
94 | return _nodeSectionsArray;
95 | }
96 |
97 | - (void)loadNodesWithBlock:(void(^)(NSArray* nodeSectionsArray, NSError *error))block
98 | {
99 | if (self.isLoading) {
100 | return;
101 | }
102 | else {
103 | self.isLoading = YES;
104 | }
105 |
106 | NSString* relativePath = [self relativePath];
107 | [[self apiSharedClient] GET:relativePath parameters:nil
108 | success:^(AFHTTPRequestOperation *operation, id responseObject) {
109 | self.isLoading = NO;
110 | if ([responseObject isKindOfClass:[NSArray class]]) {
111 | NSArray* sectionsArray = [self entitiesParsedFromResponseObject:responseObject];
112 | if (block) {
113 | block(sectionsArray, nil);
114 | }
115 | }
116 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
117 | self.isLoading = NO;
118 | if (block) {
119 | block(nil, error);
120 | }
121 | }];
122 | }
123 |
124 | ///////////////////////////////////////////////////////////////////////////////////////////////////
125 | - (void)cancelRequstOperation
126 | {
127 | if (self.isLoading) {
128 | [[RCAPIClient sharedClient] cancelAllHTTPOperationsWithPath:[self relativePath]];
129 | self.isLoading = NO;
130 | }
131 | }
132 |
133 | @end
134 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCForumTopicsModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCForumTopicsModel.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCBaseTableModel.h"
10 |
11 | @interface RCForumTopicsModel : RCBaseTableModel
12 | @property (nonatomic, assign) RCForumTopicsType topicsType;
13 | @property (nonatomic, copy) NSString* nodeName;
14 | @property (nonatomic, assign) NSUInteger nodeId;
15 | @property (nonatomic, copy) NSString* loginId;
16 | @end
17 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCForumTopicsModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCForumTopicsModel.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCForumTopicsModel.h"
10 | #import "RCAPIClient.h"
11 | #import "RCTopicCell.h"
12 | #import "RCTopicEntity.h"
13 |
14 | @interface RCForumTopicsModel()
15 |
16 | @end
17 |
18 | @implementation RCForumTopicsModel
19 |
20 | ///////////////////////////////////////////////////////////////////////////////////////////////////
21 | - (id)initWithDelegate:(id)delegate
22 | {
23 | self = [super initWithDelegate:delegate];
24 | if (self) {
25 |
26 | }
27 | return self;
28 | }
29 |
30 | ///////////////////////////////////////////////////////////////////////////////////////////////////
31 | - (NSString*)relativePath
32 | {
33 | NSString* path = nil;
34 | switch (self.topicsType) {
35 | case RCForumTopicsType_LatestActivity:
36 | path = [RCAPIClient relativePathForTopicsWithPageIndex:self.pageIndex
37 | pageSize:self.pageSize];
38 | break;
39 | case RCForumTopicsType_NodeList:
40 | path = [RCAPIClient relativePathForTopicsWithNodeId:self.nodeId
41 | pageIndex:self.pageIndex
42 | pageSize:self.pageSize];
43 | break;
44 |
45 | case RCForumTopicsType_UserPosted:
46 | path = [RCAPIClient relativePathForPostedTopicsWithUserLoginId:self.loginId
47 | pageIndex:self.pageIndex
48 | pageSize:self.pageSize];
49 | break;
50 |
51 | case RCForumTopicsType_UserFavorited:
52 | path = [RCAPIClient relativePathForFavoritedTopicsWithUserLoginId:self.loginId
53 | pageIndex:self.pageIndex
54 | pageSize:self.pageSize];
55 | break;
56 |
57 | default:
58 | break;
59 | }
60 | return path;
61 | }
62 |
63 | ///////////////////////////////////////////////////////////////////////////////////////////////////
64 | - (Class)objectClass
65 | {
66 | return [RCTopicEntity class];
67 | }
68 |
69 | ///////////////////////////////////////////////////////////////////////////////////////////////////
70 | - (Class)cellClass
71 | {
72 | return [RCTopicCell class];
73 | }
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCLoginModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCSignModel.h
3 | // RubyChina
4 | //
5 | // Created by jimneylee on 13-7-25.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "RCAccountEntity.h"
11 |
12 | @interface RCLoginModel : NSObject
13 |
14 | - (void)loginWithUsername:(NSString*)username password:(NSString*)password
15 | block:(void(^)(RCAccountEntity* user, NSError *error))block;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCLoginModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCLoginModel.m
3 | // RubyChina
4 | //
5 | // Created by jimneylee on 13-7-25.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCLoginModel.h"
10 | #import "RCAPIClient.h"
11 | //#import "AFJSONRequestOperation.h"
12 | #import "NSDataAdditions.h"
13 |
14 | ///////////////////////////////////////////////////////////////////////////////////////////////////
15 | ///////////////////////////////////////////////////////////////////////////////////////////////////
16 | ///////////////////////////////////////////////////////////////////////////////////////////////////
17 | @implementation RCLoginModel
18 |
19 | ///////////////////////////////////////////////////////////////////////////////////////////////////
20 | - (void)loginWithUsername:(NSString*)username password:(NSString*)password
21 | block:(void(^)(RCAccountEntity* user, NSError *error))block
22 | {
23 | NSString* path = [RCAPIClient relativePathForSignIn];
24 | #if 1
25 | // 由于登录的接口与其他接口base_url不太一样,后台没有放到api路径下,故单独处理
26 | // ruby-china.org/account/sign_in.json
27 | AFHTTPRequestOperationManager *httpClient = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:
28 | [NSURL URLWithString:HOST_URL]];
29 | [httpClient.requestSerializer setAuthorizationHeaderFieldWithUsername:username password:password];
30 | [httpClient POST:path parameters:nil
31 | success:^(AFHTTPRequestOperation *operation, id responseObject) {
32 | if ([responseObject isKindOfClass:[NSDictionary class]]) {
33 | RCAccountEntity* account = [RCAccountEntity entityWithDictionary:responseObject];
34 | [RCGlobalConfig setMyLoginId:account.loginId];
35 | [RCGlobalConfig setMyToken:account.privateToken];
36 | [RCAccountEntity storePrivateToken:account.privateToken forLoginId:account.loginId];
37 | if (block) {
38 | block(account, nil);
39 | }
40 | }
41 | else {
42 | if (block) {
43 | NSError* error = [[NSError alloc] init];
44 | block(nil, error);
45 | }
46 | }
47 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
48 | //NSDictionary* info = [error.userInfo objectForKey:@"NSLocalizedRecoverySuggestion"];
49 | //NSLog(@"error: %@", [info objectForKey:@"error"]);
50 | //NSLog(@"error: %@", error);
51 | if (block) {
52 | block(nil, error);
53 | }
54 | }];
55 | #endif
56 | }
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCPostModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCReplyModel.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/11/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "RCTopicEntity.h"
11 |
12 | @interface RCPostModel : NSObject
13 | - (void)postNewTopicWithTitle:(NSString*)title
14 | body:(NSString*)body
15 | nodeId:(NSUInteger)nodeId
16 | success:(void(^)(RCTopicEntity* topicEntity))success
17 | failure:(void(^)(NSError *error))failure;
18 | @end
19 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCPostModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCReplyModel.m
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/11/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCPostModel.h"
10 | #import "RCAPIClient.h"
11 | #import "AFHTTPRequestOperation.h"
12 |
13 | @implementation RCPostModel
14 |
15 | ///////////////////////////////////////////////////////////////////////////////////////////////////
16 | - (void)postNewTopicWithTitle:(NSString*)title
17 | body:(NSString*)body
18 | nodeId:(NSUInteger)nodeId
19 | success:(void(^)(RCTopicEntity* topicEntity))success
20 | failure:(void(^)(NSError *error))failure
21 | {
22 | if (title.length && body.length && nodeId > 0) {
23 | NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
24 | [parameters setObject:title forKey:@"title"];
25 | [parameters setObject:body forKey:@"body"];
26 | [parameters setObject:[NSNumber numberWithUnsignedInt:nodeId] forKey:@"node_id"];
27 | [parameters setObject:[RCGlobalConfig myToken] forKey:@"token"];
28 |
29 | NSString* path = [RCAPIClient relativePathForPostNewTopic];
30 | [[RCAPIClient sharedClient] POST:path parameters:parameters
31 | success:^(AFHTTPRequestOperation *operation, id responseObject) {
32 |
33 | BOOL successFlag = NO;
34 | if ([responseObject isKindOfClass:[NSDictionary class]]) {
35 | RCTopicEntity* topicEntity = [RCTopicEntity entityWithDictionary:responseObject];
36 | if (topicEntity) {
37 | success(topicEntity);
38 | successFlag = YES;
39 | }
40 | }
41 |
42 | if (!successFlag) {
43 | failure(nil);
44 | }
45 | }
46 | failure:^(AFHTTPRequestOperation *operation, NSError *error) {
47 | NSLog(@"%@", error);
48 | failure(error);
49 | }];
50 | }
51 | }
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCReplyModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCReplyModel.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/11/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "RCReplyEntity.h"
11 |
12 | @interface RCReplyModel : NSObject
13 | - (void)replyTopicId:(unsigned long)topicId
14 | body:(NSString*)body
15 | success:(void(^)(RCReplyEntity* replyEntity))success
16 | failure:(void(^)(NSError *error))failure;
17 | @end
18 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCReplyModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCReplyModel.m
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/11/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCReplyModel.h"
10 | #import "RCAPIClient.h"
11 | #import "AFHTTPRequestOperation.h"
12 |
13 | @implementation RCReplyModel
14 |
15 | ///////////////////////////////////////////////////////////////////////////////////////////////////
16 | - (void)replyTopicId:(unsigned long)topicId
17 | body:(NSString*)body
18 | success:(void(^)(RCReplyEntity* replyEntity))success
19 | failure:(void(^)(NSError *error))failure
20 | {
21 | if (body.length) {
22 | NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
23 | [parameters setObject:body forKey:@"body"];
24 | [parameters setObject:[RCGlobalConfig myToken] forKey:@"token"];
25 |
26 | NSString* path = [RCAPIClient relativePathForReplyTopicId:topicId];
27 | [[RCAPIClient sharedClient] POST:path parameters:parameters
28 | success:^(AFHTTPRequestOperation *operation, id responseObject) {
29 | BOOL successFlag = NO;
30 | if ([responseObject isKindOfClass:[NSDictionary class]]) {
31 | RCReplyEntity* replyEntity = [RCReplyEntity entityWithDictionary:responseObject];
32 | if (replyEntity) {
33 | success(replyEntity);
34 | successFlag = YES;
35 | }
36 | }
37 |
38 | if (!successFlag) {
39 | failure(nil);
40 | }
41 | }
42 | failure:^(AFHTTPRequestOperation *operation, NSError *error) {
43 | failure(error);
44 | }];
45 | }
46 | }
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCTopMembersModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCCoolSitesModel.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-12.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | @interface RCTopMembersModel : NIMutableTableViewModel
10 |
11 | @property (nonatomic, strong) NSMutableArray* topMembersArray;
12 | @property (nonatomic, assign) BOOL isLoading;
13 |
14 | - (void)loadTopMembersWithBlock:(void(^)(NSArray* topMembersArray, NSError* error))block;
15 | - (void)cancelRequstOperation;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCTopMembersModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCCoolSitesModel.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-12.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCTopMembersModel.h"
10 | #import "RCAPIClient.h"
11 | #import "RCUserEntity.h"
12 |
13 | @implementation RCTopMembersModel
14 |
15 | ///////////////////////////////////////////////////////////////////////////////////////////////////
16 | - (NSString*)relativePath
17 | {
18 | // 暂时未分页
19 | return [RCAPIClient relativePathForTopMembersWithPageIndex:0 pageSize:0];
20 | }
21 |
22 | ///////////////////////////////////////////////////////////////////////////////////////////////////
23 | - (void)loadTopMembersWithBlock:(void(^)(NSArray* siteSectionsArray, NSError* error))block
24 | {
25 | if (self.isLoading) {
26 | return;
27 | }
28 | else {
29 | self.isLoading = YES;
30 | }
31 | [[RCAPIClient sharedClient] GET:[self relativePath] parameters:nil
32 | success:^(AFHTTPRequestOperation *operation, id responseObject) {
33 | self.isLoading = NO;
34 | if ([responseObject isKindOfClass:[NSArray class]]) {
35 | NSArray* sourceArray = (NSArray*)responseObject;
36 | if (sourceArray.count) {
37 | RCUserEntity* user = nil;
38 | NSMutableArray* topMembersArray = [NSMutableArray arrayWithCapacity:sourceArray.count];
39 | for (NSDictionary* dic in sourceArray) {
40 | user = [RCUserEntity entityWithDictionary:dic];
41 | [topMembersArray addObject:user];
42 | }
43 | self.topMembersArray = topMembersArray;
44 | if (block) {
45 | block(topMembersArray, nil);
46 | return;
47 | }
48 | }
49 | }
50 | if (block) {
51 | NSError* error = [[NSError alloc] init];
52 | block(nil, error);
53 | }
54 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
55 | self.isLoading = NO;
56 | if (block) {
57 | block(nil, error);
58 | }
59 | }];
60 | }
61 |
62 | ///////////////////////////////////////////////////////////////////////////////////////////////////
63 | - (void)cancelRequstOperation
64 | {
65 | if (self.isLoading) {
66 | [[RCAPIClient sharedClient] cancelAllHTTPOperationsWithPath:[self relativePath]];
67 | self.isLoading = NO;
68 | }
69 | }
70 |
71 | @end
72 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCTopMembersModel_list.h:
--------------------------------------------------------------------------------
1 | //
2 | // SMPublicTimelineModel.h
3 | // SinaMBlogNimbus
4 | //
5 | // Created by Lee jimney on 10/30/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCBaseTableModel.h"
10 |
11 | @interface RCTopMembersModel : RCBaseTableModel
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCTopMembersModel_list.m:
--------------------------------------------------------------------------------
1 | //
2 | // SMPublicTimelineModel.m
3 | // SinaMBlogNimbus
4 | //
5 | // Created by Lee jimney on 10/30/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCTopMembersModel.h"
10 | #import "RCUserEntity.h"
11 | #import "RCUserCell.h"
12 |
13 | @implementation RCTopMembersModel
14 |
15 | ///////////////////////////////////////////////////////////////////////////////////////////////////
16 | - (id)initWithDelegate:(id)delegate
17 | {
18 | self = [super initWithDelegate:delegate];
19 | if (self) {
20 | // TODO:数据一次性获取过来,没有分页,后面建议后台做分页
21 | self.perpageCount = NSIntegerMax;
22 | }
23 | return self;
24 | }
25 |
26 | ///////////////////////////////////////////////////////////////////////////////////////////////////
27 | - (NSString*)relativePath
28 | {
29 | return [RCAPIClient relativePathForTopMembersWithPageCounter:self.pageCounter
30 | perpageCount:self.perpageCount];
31 | }
32 |
33 | ///////////////////////////////////////////////////////////////////////////////////////////////////
34 | - (Class)objectClass
35 | {
36 | return [RCUserEntity class];
37 | }
38 |
39 | ///////////////////////////////////////////////////////////////////////////////////////////////////
40 | - (Class)cellClass
41 | {
42 | return [RCUserCell class];
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCTopicActionModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopicActionModel.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/11/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM(NSInteger, RCTopicActionType) {
12 | RCTopicActionType_Follow,
13 | RCTopicActionType_Unfollow,
14 | RCTopicActionType_Favorite
15 | };
16 |
17 | @interface RCTopicActionModel : NSObject
18 |
19 | - (void)followTopicId:(unsigned long)topicId
20 | success:(void(^)())success
21 | failure:(void(^)(NSError *error))failure;
22 |
23 | - (void)unfollowTopicId:(unsigned long)topicId
24 | success:(void(^)())success
25 | failure:(void(^)(NSError *error))failure;
26 |
27 | - (void)favoriteTopicId:(unsigned long)topicId
28 | success:(void(^)())success
29 | failure:(void(^)(NSError *error))failure;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCTopicActionModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopicActionModel.m
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/11/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCTopicActionModel.h"
10 | #import "RCAPIClient.h"
11 | #import "AFHTTPRequestOperation.h"
12 |
13 | @implementation RCTopicActionModel
14 |
15 | ///////////////////////////////////////////////////////////////////////////////////////////////////
16 | - (NSString*)relativePathWithTopicId:(unsigned long)topicId actionType:(RCTopicActionType)actionType
17 | {
18 | NSString* path = nil;
19 | switch (actionType) {
20 | case RCTopicActionType_Follow:
21 | path = [RCAPIClient relativePathForFollowTopicId:topicId];
22 | break;
23 |
24 | case RCTopicActionType_Unfollow:
25 | path = [RCAPIClient relativePathForUnfollowTopicId:topicId];
26 | break;
27 |
28 | case RCTopicActionType_Favorite:
29 | path = [RCAPIClient relativePathForFavoriteTopicId:topicId];
30 | break;
31 |
32 | default:
33 | break;
34 | }
35 | return path;
36 | }
37 |
38 | ///////////////////////////////////////////////////////////////////////////////////////////////////
39 | - (void)followTopicId:(unsigned long)topicId
40 | success:(void(^)())success
41 | failure:(void(^)(NSError *error))failure
42 | {
43 | [self doActionWithTopicId_json_response:topicId actionType:RCTopicActionType_Follow
44 | success:success failure:failure];
45 | }
46 |
47 | ///////////////////////////////////////////////////////////////////////////////////////////////////
48 | - (void)unfollowTopicId:(unsigned long)topicId
49 | success:(void(^)())success
50 | failure:(void(^)(NSError *error))failure
51 | {
52 | [self doActionWithTopicId_json_response:topicId actionType:RCTopicActionType_Unfollow
53 | success:success failure:failure];
54 | }
55 |
56 | ///////////////////////////////////////////////////////////////////////////////////////////////////
57 | - (void)favoriteTopicId:(unsigned long)topicId
58 | success:(void(^)())success
59 | failure:(void(^)(NSError *error))failure
60 | {
61 | [self doActionWithTopicId:topicId actionType:RCTopicActionType_Favorite
62 | success:success failure:failure];
63 | }
64 |
65 | ///////////////////////////////////////////////////////////////////////////////////////////////////
66 | // 返回的是json数据 => follow unfollow,不同于favorite,DT!:(
67 | - (void)doActionWithTopicId_json_response:(unsigned long)topicId
68 | actionType:(RCTopicActionType)actionType
69 | success:(void(^)())success
70 | failure:(void(^)(NSError *error))failure
71 | {
72 | if (topicId > 0) {
73 | NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
74 | [parameters setObject:[RCGlobalConfig myToken] forKey:@"token"];
75 |
76 | NSString* path = [self relativePathWithTopicId:topicId actionType:actionType];
77 | [[RCAPIClient sharedClient] POST:path parameters:parameters
78 | success:^(AFHTTPRequestOperation *operation, id responseObject) {
79 | NSLog(@"%@", responseObject);
80 | success();
81 | }
82 | failure:^(AFHTTPRequestOperation *operation, NSError *error) {
83 | // TODO: 已关注,返回不是json,建议后台统一处理
84 | // (JSON text did not start with array or object and option to allow fragments not set.)
85 | NSLog(@"%@", error);
86 | failure(error);
87 | }];
88 | }
89 | }
90 |
91 | ///////////////////////////////////////////////////////////////////////////////////////////////////
92 | // 返回是ture or false => favorite
93 | - (void)doActionWithTopicId:(unsigned long)topicId
94 | actionType:(RCTopicActionType)actionType
95 | success:(void(^)())success
96 | failure:(void(^)(NSError *error))failure
97 | {
98 | #warning "to use af2.0"
99 | #if 0
100 | // 参考:http://stackoverflow.com/questions/9562459/afnetworking-posting-malformed-json-single-quotes-and-object-refs
101 | if (topicId > 0) {
102 | NSMutableDictionary* parameters = [NSMutableDictionary dictionary];
103 | [parameters setObject:[RCGlobalConfig myToken] forKey:@"token"];
104 |
105 | NSString* path = [self relativePathWithTopicId:topicId actionType:actionType];
106 | NSError *error = nil;
107 | NSData* jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:&error];
108 |
109 | AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:HOST_API_URL]];
110 | [httpClient setParameterEncoding:AFFormURLParameterEncoding];
111 | NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST"
112 | path:path
113 | parameters:nil];
114 | NSMutableData *body = [NSMutableData data];
115 | [body appendData:jsonData];
116 | [request setHTTPBody:body];
117 | [request setHTTPMethod:@"POST"];
118 | [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
119 | [request setValue:@"application/json" forHTTPHeaderField:@"content-type"];
120 |
121 | AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
122 | [httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
123 | [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
124 | NSString* resultString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
125 | NSLog(@"Response: %@", resultString);
126 | if ([resultString isEqualToString:@"true"]) {
127 | success();
128 | }
129 | else {
130 | failure(nil);
131 | }
132 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
133 | NSLog(@"Error: %@", error);
134 | failure(nil);
135 | }];
136 | [operation start];
137 | }
138 | #endif
139 | }
140 | @end
141 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCTopicDetailModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopicDetailModel.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCBaseTableModel.h"
10 | #import "RCTopicDetailEntity.h"
11 |
12 | @interface RCTopicDetailModel : RCBaseTableModel
13 | @property (nonatomic, assign) unsigned long topicId;
14 | @property (nonatomic, strong) RCTopicDetailEntity* topicDetailEntity;
15 | @end
16 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCTopicDetailModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopicDetailModel.m
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCTopicDetailModel.h"
10 | #import "RCReplyCell.h"
11 | #import "RCReplyEntity.h"
12 |
13 | @implementation RCTopicDetailModel
14 |
15 | ///////////////////////////////////////////////////////////////////////////////////////////////////
16 | - (id)initWithDelegate:(id)delegate
17 | {
18 | self = [super initWithDelegate:delegate];
19 | if (self) {
20 |
21 | // TODO:数据一次性获取过来,没有分页,后面建议后台做分页
22 | if (ForumBaseAPIType_RubyChina == FORUM_BASE_API_TYPE) {
23 | self.pageSize = NSIntegerMax;
24 | }
25 |
26 | //TOPIC_PAGE_SIZE=100 see v2ex https://github.com/livid/v2ex/blob/5d8764c8ec0d138a308b5c90003261c5673124a6/topic.py
27 | else if (ForumBaseAPIType_V2EX == FORUM_BASE_API_TYPE) {
28 | self.pageSize = 100;
29 | }
30 | }
31 | return self;
32 | }
33 |
34 | ///////////////////////////////////////////////////////////////////////////////////////////////////
35 | ///////////////////////////////////////////////////////////////////////////////////////////////////
36 | #pragma mark - Override
37 |
38 | ///////////////////////////////////////////////////////////////////////////////////////////////////
39 | - (NSString*)relativePath
40 | {
41 | // TODO: set type
42 | if (ForumBaseAPIType_RubyChina == FORUM_BASE_API_TYPE) {
43 | return [RCAPIClient relativePathForTopicDetailWithTopicId:self.topicId];
44 | }
45 | else if (ForumBaseAPIType_V2EX == FORUM_BASE_API_TYPE) {
46 | return [RCAPIClient relativePathForTopicRepliesWithTopicId:self.topicId
47 | pageIndex:self.pageIndex
48 | pageSize:self.pageSize];
49 | }
50 | return nil;
51 | }
52 |
53 | ///////////////////////////////////////////////////////////////////////////////////////////////////
54 | - (NSString*)listKey
55 | {
56 | return JSON_REPLIES_LIST;
57 | }
58 |
59 | ///////////////////////////////////////////////////////////////////////////////////////////////////
60 | - (Class)objectClass
61 | {
62 | return [RCReplyEntity class];
63 | }
64 |
65 | ///////////////////////////////////////////////////////////////////////////////////////////////////
66 | - (Class)cellClass
67 | {
68 | return [RCReplyCell class];
69 | }
70 |
71 | ///////////////////////////////////////////////////////////////////////////////////////////////////
72 | - (NSArray*)entitiesParsedFromResponseObject:(id)responseObject
73 | {
74 | // 1、parse topic detail body
75 | self.topicDetailEntity = [RCTopicDetailEntity entityWithDictionary:responseObject];
76 |
77 | // 2、parse replies list with key: JSON_REPLIES_LIST
78 | NSArray* entities = [super entitiesParsedFromResponseObject:responseObject];
79 | RCReplyEntity* o = nil;
80 | for (NSUInteger i = 0; i < entities.count; i++) {
81 | o = entities[i];
82 | o.floorNumber = i+1;
83 | }
84 |
85 | // 3、call inline sort
86 | //entities = [entities sortedArrayUsingSelector:@selector(compare:)];
87 |
88 | return entities;
89 | }
90 |
91 | @end
92 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCUserHomepageModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopicDetailModel.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCBaseTableModel.h"
10 | #import "RCUserFullEntity.h"
11 |
12 | @interface RCUserHomepageModel : RCBaseTableModel
13 | @property (nonatomic, copy) NSString* loginId;
14 | @property (nonatomic, strong) RCUserFullEntity* userEntity;//TODO:replace with RCUserFullEntity
15 | @end
16 |
--------------------------------------------------------------------------------
/JLRubyChina/Models/RCUserHomepageModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopicDetailModel.m
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCUserHomepageModel.h"
10 | #import "RCTopicCell.h"
11 | #import "RCTopicEntity.h"
12 |
13 | @implementation RCUserHomepageModel
14 |
15 | ///////////////////////////////////////////////////////////////////////////////////////////////////
16 | - (id)initWithDelegate:(id)delegate
17 | {
18 | self = [super initWithDelegate:delegate];
19 | if (self) {
20 | // TODO:数据一次性获取过来,没有分页,后面建议后台做分页
21 | self.pageSize = NSIntegerMax;
22 | }
23 | return self;
24 | }
25 |
26 | ///////////////////////////////////////////////////////////////////////////////////////////////////
27 | ///////////////////////////////////////////////////////////////////////////////////////////////////
28 | #pragma mark - Override
29 |
30 | ///////////////////////////////////////////////////////////////////////////////////////////////////
31 | - (NSString*)relativePath
32 | {
33 | if (self.loginId.length) {
34 | return [RCAPIClient relativePathForVisitUserHomepageWithLoginId:self.loginId];
35 | }
36 | return nil;
37 | }
38 |
39 | ///////////////////////////////////////////////////////////////////////////////////////////////////
40 | - (NSString*)listKey
41 | {
42 | return JSON_TOPICS_LIST;
43 | }
44 |
45 | ///////////////////////////////////////////////////////////////////////////////////////////////////
46 | - (Class)objectClass
47 | {
48 | return [RCTopicEntity class];
49 | }
50 |
51 | ///////////////////////////////////////////////////////////////////////////////////////////////////
52 | - (Class)cellClass
53 | {
54 | return [RCTopicCell class];
55 | }
56 |
57 | ///////////////////////////////////////////////////////////////////////////////////////////////////
58 | - (NSArray*)entitiesParsedFromResponseObject:(id)responseObject
59 | {
60 | // 1、parse topic detail body
61 | self.userEntity = [RCUserFullEntity entityWithDictionary:responseObject];
62 |
63 | // 2、parse replies list with key: JSON_REPLIES_LIST
64 | NSArray* entities = [super entitiesParsedFromResponseObject:responseObject];
65 | return entities;
66 | }
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/JLRubyChina/RCAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // JLAppDelegate.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "JASidePanelController.h"
11 |
12 | @interface RCAppDelegate : UIResponder
13 |
14 | @property (strong, nonatomic) UIWindow *window;
15 | @property (strong, nonatomic) JASidePanelController *sidePanelController;
16 | @end
17 |
--------------------------------------------------------------------------------
/JLRubyChina/RCGlobalConfig.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCGlobalConfig.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | // API 接口类型:ruby-china、v2ex
12 | typedef enum {
13 | ForumBaseAPIType_RubyChina,
14 | ForumBaseAPIType_V2EX
15 | }ForumBaseAPIType;
16 |
17 | // 帖子类型
18 | typedef enum {
19 | RCForumTopicsType_LatestActivity,//当前活跃帖子
20 | RCForumTopicsType_HighQuality,//优质帖子
21 | RCForumTopicsType_NeverReviewed,//无人问津
22 | RCForumTopicsType_LatestCreate,//最新创建
23 | RCForumTopicsType_NodeList,//某一分类帖子
24 | RCForumTopicsType_UserPosted,//某个用户发的
25 | RCForumTopicsType_UserFavorited//某个用户收藏
26 | }RCForumTopicsType;
27 |
28 | @interface RCGlobalConfig : NSObject
29 |
30 | //Global Data
31 | + (NSString*)myToken;
32 | + (void)setMyToken:(NSString*)token;
33 | + (NSString*)myLoginId;
34 | + (void)setMyLoginId:(NSString*)loginId;
35 | + (void)parseAppConfig;
36 | + (ForumBaseAPIType)forumBaseAPIType;
37 |
38 | // Global UI
39 | + (MBProgressHUD*)HUDShowMessage:(NSString*)msg addedToView:(UIView*)view;
40 | + (UIBarButtonItem*)createBarButtonItemWithTitle:(NSString*)buttonTitle Target:(id)target action:(SEL)action;
41 | + (UIBarButtonItem*)createMenuBarButtonItemWithTarget:(id)target action:(SEL)action;
42 | + (UIBarButtonItem*)createRefreshBarButtonItemWithTarget:(id)target action:(SEL)action;
43 | + (void)showLoginControllerFromNavigationController:(UINavigationController*)navigationController;
44 |
45 | // emoji reverse code
46 | + (NSDictionary *)emojiReverseAliases;
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/JLRubyChina/RCGlobalConfig.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCGlobalConfig.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCGlobalConfig.h"
10 | #import "RCLoginC.h"
11 |
12 | static NSString* myToken = nil;
13 | static NSString* myLoginId = nil;
14 | static ForumBaseAPIType forumBaseAPIType = ForumBaseAPIType_RubyChina;
15 |
16 | @implementation RCGlobalConfig
17 |
18 | ///////////////////////////////////////////////////////////////////////////////////////////////////
19 | ///////////////////////////////////////////////////////////////////////////////////////////////////
20 | #pragma mark - Global Data
21 |
22 | ///////////////////////////////////////////////////////////////////////////////////////////////////
23 | + (NSString*)myToken
24 | {
25 | return myToken;
26 | }
27 |
28 | ///////////////////////////////////////////////////////////////////////////////////////////////////
29 | + (void)setMyToken:(NSString*)token
30 | {
31 | myToken = [token copy];
32 | }
33 |
34 | ///////////////////////////////////////////////////////////////////////////////////////////////////
35 | + (NSString*)myLoginId
36 | {
37 | return myLoginId;
38 | }
39 |
40 | ///////////////////////////////////////////////////////////////////////////////////////////////////
41 | + (void)setMyLoginId:(NSString*)loginId
42 | {
43 | myLoginId = [loginId copy];
44 | }
45 |
46 | ///////////////////////////////////////////////////////////////////////////////////////////////////
47 | ///////////////////////////////////////////////////////////////////////////////////////////////////
48 | #pragma mark - App Config
49 |
50 | ///////////////////////////////////////////////////////////////////////////////////////////////////
51 | + (void)parseAppConfig
52 | {
53 | NSString* apiTypeString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"HOST_BASE_API_TYPE"];
54 | if (NSOrderedSame == [apiTypeString caseInsensitiveCompare:@"rubychina"]) {
55 | forumBaseAPIType = ForumBaseAPIType_RubyChina;
56 | }
57 | else if (NSOrderedSame == [apiTypeString caseInsensitiveCompare:@"v2ex"]) {
58 | forumBaseAPIType = ForumBaseAPIType_V2EX;
59 | }
60 | else {
61 | forumBaseAPIType = ForumBaseAPIType_RubyChina;
62 | }
63 | }
64 |
65 | ///////////////////////////////////////////////////////////////////////////////////////////////////
66 | + (ForumBaseAPIType)forumBaseAPIType
67 | {
68 | return forumBaseAPIType;
69 | }
70 |
71 | ///////////////////////////////////////////////////////////////////////////////////////////////////
72 | ///////////////////////////////////////////////////////////////////////////////////////////////////
73 | #pragma mark - Global UI
74 |
75 | ///////////////////////////////////////////////////////////////////////////////////////////////////
76 | + (MBProgressHUD*)HUDShowMessage:(NSString*)msg addedToView:(UIView*)view
77 | {
78 | static MBProgressHUD* hud = nil;
79 | if (!hud) {
80 | hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
81 | }
82 | hud.mode = MBProgressHUDModeText;
83 | hud.labelText = msg;
84 | hud.hidden = NO;
85 | hud.alpha = 1.0f;
86 | [hud hide:YES afterDelay:1.0f];
87 | return hud;
88 | }
89 |
90 | ///////////////////////////////////////////////////////////////////////////////////////////////////
91 | + (UIBarButtonItem*)createBarButtonItemWithTitle:(NSString*)buttonTitle Target:(id)target action:(SEL)action
92 | {
93 | UIBarButtonItem* item = nil;
94 | item = [[UIBarButtonItem alloc] initWithTitle:buttonTitle
95 | style:UIBarButtonItemStylePlain
96 | target:target
97 | action:action];
98 | return item;
99 | }
100 |
101 | ///////////////////////////////////////////////////////////////////////////////////////////////////
102 | + (UIBarButtonItem*)createMenuBarButtonItemWithTarget:(id)target action:(SEL)action
103 | {
104 | return [[UIBarButtonItem alloc] initWithImage:[UIImage nimbusImageNamed:@"icon_menu.png"]
105 | style:UIBarButtonItemStylePlain
106 | target:target action:action];
107 | }
108 |
109 | ///////////////////////////////////////////////////////////////////////////////////////////////////
110 | + (UIBarButtonItem*)createRefreshBarButtonItemWithTarget:(id)target action:(SEL)action
111 | {
112 | UIBarButtonItem* item = nil;
113 | item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh
114 | target:target action:action];
115 | return item;
116 | }
117 |
118 | ///////////////////////////////////////////////////////////////////////////////////////////////////
119 | + (void)showLoginControllerFromNavigationController:(UINavigationController*)navigationController
120 | {
121 | RCLoginC* loginC = [[RCLoginC alloc] initWithStyle:UITableViewStyleGrouped];
122 | [navigationController pushViewController:loginC animated:YES];
123 | }
124 |
125 | ///////////////////////////////////////////////////////////////////////////////////////////////////
126 | // emoji -> code
127 | + (NSDictionary *)emojiReverseAliases {
128 | static NSDictionary *_emojiReverseAliases;
129 | static dispatch_once_t onceToken;
130 | dispatch_once(&onceToken, ^{
131 | _emojiReverseAliases = @{
132 | @"\U0001F604" : @":smile:",
133 | @"\U0001F60A" : @":blush:",
134 | @"\U0001F603" : @":smiley:",
135 | @"\U0000263A" : @":relaxed:",
136 | @"\U0001F609" : @":wink:",
137 | @"\U0001F60D" : @":heart_eyes:",
138 | @"\U0001F618" : @":kissing_heart:",
139 | @"\U0001F61A" : @":kissing_closed_eyes:",
140 | @"\U0001F633" : @":flushed:",
141 | @"\U0001F60C" : @":relieved:",
142 | @"\U0001F601" : @":grin:",
143 | @"\U0001F61C" : @":stuck_out_tongue_winking_eye:",
144 | @"\U0001F61D" : @":stuck_out_tongue_closed_eyes:",
145 | @"\U0001F612" : @":unamused:",
146 | @"\U0001F60F" : @":smirk:",
147 | @"\U0001F613" : @":sweat:",
148 | @"\U0001F614" : @":pensive:",
149 | @"\U0001F61E" : @":disappointed:",
150 | @"\U0001F616" : @":confounded:",
151 | @"\U0001F625" : @":disappointed_relieved:",
152 | @"\U0001F630" : @":cold_sweat:",
153 | @"\U0001F628" : @":fearful:",
154 | @"\U0001F623" : @":persevere:",
155 | @"\U0001F622" : @":cry:",
156 | @"\U0001F62D" : @":sob:",
157 | @"\U0001F602" : @":joy:",
158 | @"\U0001F632" : @":astonished:",
159 | @"\U0001F631" : @":scream:",
160 | };
161 | });
162 | return _emojiReverseAliases;
163 | }
164 |
165 | @end
166 |
--------------------------------------------------------------------------------
/JLRubyChina/Util/RCRegularParser.h:
--------------------------------------------------------------------------------
1 | //
2 | // SMRegularParser.h
3 | // SinaMBlog
4 | //
5 | // Created by jimneylee on 13-2-18.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RCRegularParser : NSObject
12 |
13 | // 返回所有at某人的range数组
14 | + (NSArray *)keywordRangesOfAtPersonInString:(NSString *)string;
15 |
16 | // 返回所有#楼的range数组
17 | + (NSArray *)keywordRangesOfSharpFloorInString:(NSString *)string;
18 |
19 | // 返回表情的range数组
20 | + (NSArray *)keywordRangesOfEmotionInString:(NSString *)string;
21 |
22 | // 返回图片的string数组,和去掉图片链接的trimed字符串
23 | + (NSArray *)imageUrlsInString:(NSString *)string trimedString:(NSString **)trimedString;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/JLRubyChina/Views/RCHomepageHeaderView.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCReplyCell.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | @class RCUserFullEntity;
10 | @interface RCHomepageHeaderView : UIView
11 | - (void)updateViewWithHomepageUser:(RCUserFullEntity*)user;
12 | @end
13 |
--------------------------------------------------------------------------------
/JLRubyChina/Views/RCNodeCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCNodeCell.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-11.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "NICellCatalog.h"
10 |
11 | @interface RCNodeCell : NITextCell
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/JLRubyChina/Views/RCNodeCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCNodeCell.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-11.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCNodeCell.h"
10 | #import "RCNodeEntity.h"
11 |
12 | #define TITLE_FONT_SIZE [UIFont boldSystemFontOfSize:17.f]
13 | #define SUBTITLE_FONT_SIZE [UIFont systemFontOfSize:15.f]
14 |
15 | @interface RCNodeCell()
16 | @property (nonatomic, strong) UILabel* topicsCountLabel;
17 | @end
18 | @implementation RCNodeCell
19 |
20 | ///////////////////////////////////////////////////////////////////////////////////////////////////
21 | + (CGFloat)heightForObject:(id)object atIndexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableView
22 | {
23 | CGFloat height = 0.f;
24 | CGFloat contentViewMarin = CELL_PADDING_6;
25 |
26 | height = height + contentViewMarin;
27 | height = height + TITLE_FONT_SIZE.lineHeight;
28 |
29 | height = height + CELL_PADDING_2;
30 |
31 | RCNodeEntity* o = (RCNodeEntity*)object;
32 | CGFloat kContentLength = tableView.width - contentViewMarin * 2;
33 | #if 1
34 | NSAttributedString *attributedText =
35 | [[NSAttributedString alloc] initWithString:o.summary
36 | attributes:@{NSFontAttributeName:SUBTITLE_FONT_SIZE}];
37 | CGRect rect = [attributedText boundingRectWithSize:(CGSize){kContentLength, CGFLOAT_MAX}
38 | options:NSStringDrawingUsesLineFragmentOrigin
39 | context:nil];
40 | CGSize size = rect.size;
41 | #else
42 | CGSize size = [o.summary sizeWithFont:SUBTITLE_FONT_SIZE
43 | constrainedToSize:CGSizeMake(kContentLength, FLT_MAX)
44 | lineBreakMode:NSLineBreakByWordWrapping];
45 | #endif
46 | height = height + size.height;
47 | height = height + contentViewMarin;
48 |
49 | return height;
50 | }
51 |
52 | ///////////////////////////////////////////////////////////////////////////////////////////////////
53 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
54 | {
55 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
56 | if (self) {
57 | self.selectionStyle = UITableViewCellSelectionStyleBlue;
58 | self.textLabel.font = TITLE_FONT_SIZE;
59 | self.detailTextLabel.font = SUBTITLE_FONT_SIZE;
60 | self.detailTextLabel.textColor = [UIColor darkGrayColor];
61 | self.detailTextLabel.numberOfLines = 0;
62 |
63 | // lou
64 | self.topicsCountLabel = [[UILabel alloc] initWithFrame:CGRectZero];
65 | self.topicsCountLabel.font = SUBTITLE_FONT_SIZE;
66 | self.topicsCountLabel.textColor = [UIColor blackColor];
67 | self.topicsCountLabel.textAlignment = NSTextAlignmentRight;
68 | [self.contentView addSubview:self.topicsCountLabel];
69 |
70 |
71 | }
72 | return self;
73 | }
74 |
75 |
76 | ///////////////////////////////////////////////////////////////////////////////////////////////////
77 | - (void)prepareForReuse
78 | {
79 | [super prepareForReuse];
80 | }
81 |
82 | ///////////////////////////////////////////////////////////////////////////////////////////////////
83 | - (void)layoutSubviews
84 | {
85 | [super layoutSubviews];
86 |
87 | CGFloat contentViewMarin = CELL_PADDING_6;
88 | CGFloat kContentLength = self.contentView.width - contentViewMarin * 2;
89 | self.textLabel.frame = CGRectMake(contentViewMarin, contentViewMarin, kContentLength / 2, self.textLabel.font.lineHeight);
90 | self.topicsCountLabel.frame = CGRectMake(self.textLabel.right, self.textLabel.top,
91 | kContentLength / 2, self.topicsCountLabel.font.lineHeight);
92 | #if 1
93 | NSAttributedString *attributedText =
94 | [[NSAttributedString alloc] initWithString:self.detailTextLabel.text
95 | attributes:@{NSFontAttributeName:SUBTITLE_FONT_SIZE}];
96 | CGRect rect = [attributedText boundingRectWithSize:(CGSize){kContentLength, CGFLOAT_MAX}
97 | options:NSStringDrawingUsesLineFragmentOrigin
98 | context:nil];
99 | CGSize size = rect.size;
100 | #else
101 | CGSize size = [self.detailTextLabel.text sizeWithFont:SUBTITLE_FONT_SIZE
102 | constrainedToSize:CGSizeMake(kContentLength, FLT_MAX)
103 | lineBreakMode:NSLineBreakByWordWrapping];
104 | #endif
105 | self.detailTextLabel.frame = CGRectMake(self.textLabel.left, self.textLabel.bottom + CELL_PADDING_2,
106 | kContentLength, size.height);
107 | }
108 |
109 | ///////////////////////////////////////////////////////////////////////////////////////////////////
110 | - (BOOL)shouldUpdateCellWithObject:(id)object
111 | {
112 | [super shouldUpdateCellWithObject:object];
113 | if ([object isKindOfClass:[RCNodeEntity class]]) {
114 | RCNodeEntity* o = (RCNodeEntity*)object;
115 | self.textLabel.text = o.nodeName;
116 | self.detailTextLabel.text = o.summary;
117 | self.topicsCountLabel.text = [NSString stringWithFormat:@"共有 %lu 个主题", o.topicsCount];
118 | }
119 | return YES;
120 | }
121 |
122 | @end
123 |
--------------------------------------------------------------------------------
/JLRubyChina/Views/RCReplyCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCReplyCell.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "NICellCatalog.h"
10 |
11 | // TODO:
12 | // 评论太长,收起和放下
13 | @interface RCReplyCell : NITextCell
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/JLRubyChina/Views/RCSiteCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCNodeCell.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-11.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "NICellCatalog.h"
10 |
11 | @interface RCSiteCell : NITextCell
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/JLRubyChina/Views/RCSiteCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCNodeCell.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-11.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCSiteCell.h"
10 | #import "RCSiteEntity.h"
11 |
12 | #define TITLE_FONT_SIZE [UIFont boldSystemFontOfSize:17.f]
13 | #define SUBTITLE_FONT_SIZE [UIFont systemFontOfSize:15.f]
14 |
15 | @interface RCSiteCell()
16 | @end
17 | @implementation RCSiteCell
18 |
19 | ///////////////////////////////////////////////////////////////////////////////////////////////////
20 | + (CGFloat)heightForObject:(id)object atIndexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableView
21 | {
22 | CGFloat height = 0.f;
23 | CGFloat contentViewMarin = CELL_PADDING_6;
24 |
25 | height = height + contentViewMarin;
26 | height = height + TITLE_FONT_SIZE.lineHeight;
27 |
28 | height = height + CELL_PADDING_2;
29 |
30 | RCSiteEntity* o = (RCSiteEntity*)object;
31 | CGFloat kContentLength = tableView.width - contentViewMarin * 2;
32 | #if 1
33 | NSAttributedString *attributedText =
34 | [[NSAttributedString alloc] initWithString:o.description
35 | attributes:@{NSFontAttributeName:SUBTITLE_FONT_SIZE}];
36 | CGRect rect = [attributedText boundingRectWithSize:(CGSize){kContentLength, CGFLOAT_MAX}
37 | options:NSStringDrawingUsesLineFragmentOrigin
38 | context:nil];
39 | CGSize size = rect.size;
40 | #else
41 | CGSize size = [o.description sizeWithFont:SUBTITLE_FONT_SIZE
42 | constrainedToSize:CGSizeMake(kContentLength, FLT_MAX)
43 | lineBreakMode:NSLineBreakByWordWrapping];
44 | #endif
45 | height = height + size.height;
46 | height = height + contentViewMarin;
47 |
48 | return height;
49 | }
50 |
51 | ///////////////////////////////////////////////////////////////////////////////////////////////////
52 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
53 | {
54 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
55 | if (self) {
56 | self.selectionStyle = UITableViewCellSelectionStyleBlue;
57 | self.textLabel.font = TITLE_FONT_SIZE;
58 | self.detailTextLabel.font = SUBTITLE_FONT_SIZE;
59 | self.detailTextLabel.textColor = [UIColor darkGrayColor];
60 | self.detailTextLabel.numberOfLines = 0;
61 | }
62 | return self;
63 | }
64 |
65 |
66 | ///////////////////////////////////////////////////////////////////////////////////////////////////
67 | - (void)prepareForReuse
68 | {
69 | [super prepareForReuse];
70 | }
71 |
72 | ///////////////////////////////////////////////////////////////////////////////////////////////////
73 | - (void)layoutSubviews
74 | {
75 | [super layoutSubviews];
76 |
77 | CGFloat contentViewMarin = CELL_PADDING_6;
78 | CGFloat kContentLength = self.contentView.width - contentViewMarin * 2;
79 | self.textLabel.frame = CGRectMake(contentViewMarin, contentViewMarin,
80 | kContentLength / 2, self.textLabel.font.lineHeight);
81 | #if 1
82 | NSAttributedString *attributedText =
83 | [[NSAttributedString alloc] initWithString:self.detailTextLabel.text
84 | attributes:@{NSFontAttributeName:SUBTITLE_FONT_SIZE}];
85 | CGRect rect = [attributedText boundingRectWithSize:(CGSize){kContentLength, CGFLOAT_MAX}
86 | options:NSStringDrawingUsesLineFragmentOrigin
87 | context:nil];
88 | CGSize size = rect.size;
89 | #else
90 | CGSize size = [self.detailTextLabel.text sizeWithFont:SUBTITLE_FONT_SIZE
91 | constrainedToSize:CGSizeMake(kContentLength, FLT_MAX)
92 | lineBreakMode:NSLineBreakByWordWrapping];
93 | #endif
94 | self.detailTextLabel.frame = CGRectMake(self.textLabel.left, self.textLabel.bottom + CELL_PADDING_2,
95 | kContentLength, size.height);
96 | }
97 |
98 | ///////////////////////////////////////////////////////////////////////////////////////////////////
99 | - (BOOL)shouldUpdateCellWithObject:(id)object
100 | {
101 | [super shouldUpdateCellWithObject:object];
102 | if ([object isKindOfClass:[RCSiteEntity class]]) {
103 | RCSiteEntity* o = (RCSiteEntity*)object;
104 | self.textLabel.text = o.name;
105 | self.detailTextLabel.text = o.description;
106 | }
107 | return YES;
108 | }
109 |
110 | @end
111 |
--------------------------------------------------------------------------------
/JLRubyChina/Views/RCTopicBodyView.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCTopicDetailHeaderView.h
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-11.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "RCTopicDetailEntity.h"
11 |
12 | @interface RCTopicBodyView : UIView
13 | - (void)updateViewWithTopicDetailEntity:(RCTopicDetailEntity*)topicDetailEntity;
14 | @end
15 |
--------------------------------------------------------------------------------
/JLRubyChina/Views/RCTopicCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // SMStatusCell.h
3 | // SinaMBlogNimbus
4 | //
5 | // Created by Lee jimney on 10/30/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "NICellCatalog.h"
10 |
11 | @interface RCTopicCell : NITextCell
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/JLRubyChina/Views/RCUserCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // RCReplyCell.h
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "NICellCatalog.h"
10 |
11 | @interface RCUserCell : NITextCell
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/JLRubyChina/Views/RCUserCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // RCReplyCell.m
3 | // JLRubyChina
4 | //
5 | // Created by Lee jimney on 12/10/13.
6 | // Copyright (c) 2013 jimneylee. All rights reserved.
7 | //
8 |
9 | #import "RCUserCell.h"
10 | #import
11 | #import "UIImage+nimbusImageNamed.h"
12 | #import "RCUserEntity.h"
13 | #import "UIView+findViewController.h"
14 | #import "RCUserHomepageC.h"
15 |
16 | #define NAME_FONT_SIZE [UIFont systemFontOfSize:15.f]
17 | #define DATE_FONT_SIZE [UIFont systemFontOfSize:12.f]
18 |
19 | #define HEAD_IAMGE_HEIGHT 34
20 |
21 | @interface RCUserCell()
22 | @property (nonatomic, strong) NINetworkImageView* headView;
23 | @property (nonatomic, strong) RCUserEntity* user;
24 | @end
25 |
26 | @implementation RCUserCell
27 |
28 | ///////////////////////////////////////////////////////////////////////////////////////////////////
29 | + (CGFloat)heightForObject:(id)object atIndexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableView
30 | {
31 | if ([object isKindOfClass:[RCUserEntity class]]) {
32 | CGFloat cellMargin = CELL_PADDING_4;
33 | CGFloat contentViewMarin = CELL_PADDING_6;
34 | CGFloat sideMargin = cellMargin + contentViewMarin;
35 |
36 | CGFloat height = sideMargin;
37 |
38 | // head image
39 | height = height + HEAD_IAMGE_HEIGHT;
40 |
41 | height = height + sideMargin;
42 |
43 | return height;
44 | }
45 |
46 | return 0.0f;
47 | }
48 |
49 | ///////////////////////////////////////////////////////////////////////////////////////////////////
50 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
51 | {
52 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
53 | if (self) {
54 | self.selectionStyle = UITableViewCellSelectionStyleNone;
55 |
56 | // head
57 | self.headView = [[NINetworkImageView alloc] initWithFrame:CGRectMake(0, 0, HEAD_IAMGE_HEIGHT,
58 | HEAD_IAMGE_HEIGHT)];
59 | self.headView.initialImage = [UIImage nimbusImageNamed:@"head_s.png"];
60 | [self.contentView addSubview:self.headView];
61 | UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self
62 | action:@selector(visitUserHomepage)];
63 | self.headView.userInteractionEnabled = YES;
64 | [self.headView addGestureRecognizer:tap];
65 |
66 | // name
67 | self.textLabel.font = NAME_FONT_SIZE;
68 | self.textLabel.textColor = [UIColor blackColor];
69 | self.textLabel.highlightedTextColor = self.textLabel.textColor;
70 |
71 | // date
72 | self.detailTextLabel.font = DATE_FONT_SIZE;
73 | self.detailTextLabel.textColor = [UIColor grayColor];
74 | self.detailTextLabel.highlightedTextColor = self.detailTextLabel.textColor;
75 |
76 | self.contentView.layer.borderColor = CELL_CONTENT_VIEW_BORDER_COLOR.CGColor;
77 | self.contentView.layer.borderWidth = 1.0f;
78 |
79 | self.backgroundColor = [UIColor clearColor];
80 | self.contentView.backgroundColor = CELL_CONTENT_VIEW_BG_COLOR;
81 | self.textLabel.backgroundColor = [UIColor clearColor];
82 | self.detailTextLabel.backgroundColor = [UIColor clearColor];
83 | }
84 | return self;
85 | }
86 |
87 | ///////////////////////////////////////////////////////////////////////////////////////////////////
88 | - (void)prepareForReuse
89 | {
90 | [super prepareForReuse];
91 | self.headView.image = [UIImage nimbusImageNamed:@"head_s.png"];
92 | }
93 |
94 | ///////////////////////////////////////////////////////////////////////////////////////////////////
95 | - (void)layoutSubviews
96 | {
97 | [super layoutSubviews];
98 |
99 | CGFloat cellMargin = CELL_PADDING_4;
100 | CGFloat contentViewMarin = CELL_PADDING_6;
101 | //CGFloat sideMargin = cellMargin + contentViewMarin;
102 |
103 | self.contentView.frame = CGRectMake(cellMargin, cellMargin,
104 | self.width - cellMargin * 2,
105 | self.height - cellMargin * 2);
106 |
107 | self.headView.left = contentViewMarin;
108 | self.headView.top = contentViewMarin;
109 |
110 | // name
111 | CGFloat topWidth = self.contentView.width - contentViewMarin * 2 - (self.headView.right + CELL_PADDING_10);
112 | self.textLabel.frame = CGRectMake(self.headView.right + CELL_PADDING_10, self.headView.top,
113 | topWidth / 2,
114 | self.textLabel.font.lineHeight);
115 |
116 | // date
117 | self.detailTextLabel.frame = CGRectMake(self.textLabel.left, self.textLabel.bottom,
118 | topWidth, self.detailTextLabel.font.lineHeight);
119 | }
120 |
121 | ///////////////////////////////////////////////////////////////////////////////////////////////////
122 | - (BOOL)shouldUpdateCellWithObject:(id)object
123 | {
124 | [super shouldUpdateCellWithObject:object];
125 | if ([object isKindOfClass:[RCUserEntity class]]) {
126 | RCUserEntity* o = (RCUserEntity*)object;
127 | self.user = o;
128 | if (o.avatarUrl.length) {
129 | [self.headView setPathToNetworkImage:o.avatarUrl];
130 | }
131 | else {
132 | self.headView.image = [UIImage nimbusImageNamed:@"head_s.png"];
133 | }
134 | self.textLabel.text = o.loginId;
135 | }
136 | return YES;
137 | }
138 |
139 | ///////////////////////////////////////////////////////////////////////////////////////////////////
140 | - (void)visitUserHomepage
141 | {
142 | UIViewController* superviewC = self.viewController;
143 | [RCGlobalConfig HUDShowMessage:self.user.loginId
144 | addedToView:[UIApplication sharedApplication].keyWindow];
145 | if (superviewC) {
146 | RCUserHomepageC* c = [[RCUserHomepageC alloc] initWithUserLoginId:self.user.loginId];
147 | [superviewC.navigationController pushViewController:c animated:YES];
148 | }
149 | }
150 |
151 | @end
152 |
--------------------------------------------------------------------------------
/JLRubyChina/Views/RCUserLauncherButtonView.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2011-2012 Jeff Verkoeyen
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | #import "NimbusLauncher.h"
18 |
19 | @interface RCUserLauncherViewObject : NILauncherViewObject
20 |
21 | @property (nonatomic, copy) NSString* imageUrl;
22 |
23 | - (id)initWithTitle:(NSString *)title defaultImage:(UIImage *)image imageUrl:(NSString*)imageUrl;
24 | + (id)objectWithTitle:(NSString *)title defaultImage:(UIImage *)image imageUrl:(NSString*)imageUrl;
25 |
26 | @end
27 |
28 | @interface RCUserLauncherButtonView : NILauncherButtonView
29 | @end
30 |
--------------------------------------------------------------------------------
/JLRubyChina/Views/RCUserLauncherButtonView.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2011-2012 Jeff Verkoeyen
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | #import "RCUserLauncherButtonView.h"
18 | #import
19 | #import "NimbusBadge.h"
20 |
21 |
22 | ///////////////////////////////////////////////////////////////////////////////////////////////////
23 | ///////////////////////////////////////////////////////////////////////////////////////////////////
24 | ///////////////////////////////////////////////////////////////////////////////////////////////////
25 | @implementation RCUserLauncherViewObject
26 |
27 | ///////////////////////////////////////////////////////////////////////////////////////////////////
28 | - (id)initWithTitle:(NSString *)title defaultImage:(UIImage *)image imageUrl:(NSString*)imageUrl {
29 | if ((self = [super initWithTitle:title image:image])) {
30 | _imageUrl = imageUrl;
31 | }
32 | return self;
33 | }
34 |
35 |
36 | ///////////////////////////////////////////////////////////////////////////////////////////////////
37 | + (id)objectWithTitle:(NSString *)title defaultImage:(UIImage *)image imageUrl:(NSString*)imageUrl {
38 | return [[self alloc] initWithTitle:title defaultImage:image imageUrl:imageUrl];
39 | }
40 |
41 | ///////////////////////////////////////////////////////////////////////////////////////////////////
42 | - (Class)buttonViewClass
43 | {
44 | return [RCUserLauncherButtonView class];
45 | }
46 |
47 | @end
48 |
49 | ///////////////////////////////////////////////////////////////////////////////////////////////////
50 | ///////////////////////////////////////////////////////////////////////////////////////////////////
51 | ///////////////////////////////////////////////////////////////////////////////////////////////////
52 | @interface RCUserLauncherButtonView()
53 | @property (nonatomic, strong) NINetworkImageView* networkImageview;
54 | @end
55 |
56 | ///////////////////////////////////////////////////////////////////////////////////////////////////
57 | @implementation RCUserLauncherButtonView
58 |
59 | ///////////////////////////////////////////////////////////////////////////////////////////////////
60 | - (id)initWithReuseIdentifier:(NSString *)reuseIdentifier
61 | {
62 | if ((self = [super initWithReuseIdentifier:reuseIdentifier])) {
63 |
64 | _networkImageview = [[NINetworkImageView alloc] init];
65 | _networkImageview.delegate = self;
66 | // 不需要显示,只需要负责下载图片,实现的有点恶心,但是目前没有更简单的方法,如TTImageView
67 | //[self.button addSubview:_networkImageview];
68 | }
69 | return self;
70 | }
71 |
72 | ///////////////////////////////////////////////////////////////////////////////////////////////////
73 | - (void)shouldUpdateViewWithObject:(RCUserLauncherViewObject *)object
74 | {
75 | [super shouldUpdateViewWithObject:object];
76 |
77 | if (object.imageUrl.length) {
78 | // download image to set in button's imageview
79 | [self.networkImageview setPathToNetworkImage:object.imageUrl];
80 | }
81 | }
82 |
83 | ///////////////////////////////////////////////////////////////////////////////////////////////////
84 | ///////////////////////////////////////////////////////////////////////////////////////////////////
85 | #pragma mark - NINetworkImageViewDelegate
86 |
87 | ///////////////////////////////////////////////////////////////////////////////////////////////////
88 | - (void)networkImageView:(NINetworkImageView *)imageView didLoadImage:(UIImage *)image
89 | {
90 | if (image) {
91 | [self.button setImage:image forState:UIControlStateNormal];
92 | [self.button.imageView setContentMode:UIViewContentModeScaleAspectFit];
93 | }
94 | }
95 |
96 | @end
97 |
--------------------------------------------------------------------------------
/JLRubyChina/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/JLRubyChina/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // JLRubyChina
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "RCAppDelegate.h"
12 |
13 | int main(int argc, char * argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([RCAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/JLRubyChinaTests/JLRubyChinaTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | jimneylee.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/JLRubyChinaTests/JLRubyChinaTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // JLRubyChinaTests.m
3 | // JLRubyChinaTests
4 | //
5 | // Created by jimneylee on 13-12-10.
6 | // Copyright (c) 2013年 jimneylee. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface JLRubyChinaTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation JLRubyChinaTests
16 |
17 | - (void)setUp
18 | {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown
24 | {
25 | // Put teardown code here. This method is called after the invocation of each test method in the class.
26 | [super tearDown];
27 | }
28 |
29 | - (void)testExample
30 | {
31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/JLRubyChinaTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios,'6.0'
2 | pod 'Nimbus', '~> 1.2.0'
3 | pod 'AFNetworking', '~> 2.2.3'
4 | pod 'MBProgressHUD'
5 | pod 'MTStatusBarOverlay'
6 | pod 'SSKeychain'
7 | pod 'HPGrowingTextView'
8 | pod 'SDSegmentedControl'
9 | pod 'NSStringEmojize'
10 | pod 'LTUpdate', '~> 0.0.2'
11 | pod 'RTagCloudView'
12 | pod 'NSAttributedStringMarkdownParser', '~> 0.0.1'
13 | pod 'ReactiveCocoa', '~> 2.3.1'
14 | pod 'Mantle', '~> 1.5.1'
--------------------------------------------------------------------------------
/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - AFNetworking (2.2.3):
3 | - AFNetworking/NSURLConnection
4 | - AFNetworking/NSURLSession
5 | - AFNetworking/Reachability
6 | - AFNetworking/Security
7 | - AFNetworking/Serialization
8 | - AFNetworking/UIKit
9 | - AFNetworking/NSURLConnection (2.2.3):
10 | - AFNetworking/Reachability
11 | - AFNetworking/Security
12 | - AFNetworking/Serialization
13 | - AFNetworking/NSURLSession (2.2.3):
14 | - AFNetworking/NSURLConnection
15 | - AFNetworking/Reachability (2.2.3)
16 | - AFNetworking/Security (2.2.3)
17 | - AFNetworking/Serialization (2.2.3)
18 | - AFNetworking/UIKit (2.2.3):
19 | - AFNetworking/NSURLConnection
20 | - AFNetworking/NSURLSession
21 | - fmemopen (0.0.1)
22 | - HPGrowingTextView (1.1)
23 | - LTUpdate (0.0.2)
24 | - MBProgressHUD (0.8)
25 | - MTStatusBarOverlay (0.9.1)
26 | - Nimbus (1.2.0):
27 | - Nimbus/AttributedLabel
28 | - Nimbus/Badge
29 | - Nimbus/Collections
30 | - Nimbus/Collections
31 | - Nimbus/Core
32 | - Nimbus/CSS
33 | - Nimbus/Interapp
34 | - Nimbus/Launcher
35 | - Nimbus/Models
36 | - Nimbus/NetworkControllers
37 | - Nimbus/NetworkImage
38 | - Nimbus/Overview
39 | - Nimbus/PagingScrollView
40 | - Nimbus/Photos
41 | - Nimbus/Textfield
42 | - Nimbus/WebController
43 | - Nimbus/AttributedLabel (1.2.0):
44 | - Nimbus/Core
45 | - Nimbus/Badge (1.2.0):
46 | - Nimbus/Core
47 | - Nimbus/Collections (1.2.0):
48 | - Nimbus/Core
49 | - Nimbus/Core (1.2.0)
50 | - Nimbus/CSS (1.2.0):
51 | - AFNetworking (~> 2.1)
52 | - Nimbus/Core
53 | - Nimbus/Textfield
54 | - Nimbus/Interapp (1.2.0):
55 | - Nimbus/Core
56 | - Nimbus/Launcher (1.2.0):
57 | - Nimbus/Core
58 | - Nimbus/PagingScrollView
59 | - Nimbus/Models (1.2.0):
60 | - Nimbus/Core
61 | - Nimbus/NetworkControllers (1.2.0):
62 | - Nimbus/Core
63 | - Nimbus/NetworkImage (1.2.0):
64 | - AFNetworking (~> 2.1)
65 | - Nimbus/Core
66 | - Nimbus/Overview (1.2.0):
67 | - Nimbus/Core
68 | - Nimbus/Models
69 | - Nimbus/PagingScrollView (1.2.0):
70 | - Nimbus/Core
71 | - Nimbus/Photos (1.2.0):
72 | - Nimbus/Core
73 | - Nimbus/PagingScrollView
74 | - Nimbus/Textfield (1.2.0):
75 | - Nimbus/Core
76 | - Nimbus/WebController (1.2.0):
77 | - Nimbus/Core
78 | - NSAttributedStringMarkdownParser (0.0.1):
79 | - fmemopen
80 | - NSStringEmojize (0.2.0)
81 | - RTagCloudView (1.0.0)
82 | - SDSegmentedControl (1.0.2)
83 | - SSKeychain (1.2.2)
84 |
85 | DEPENDENCIES:
86 | - AFNetworking (~> 2.2.3)
87 | - HPGrowingTextView
88 | - LTUpdate (~> 0.0.2)
89 | - MBProgressHUD
90 | - MTStatusBarOverlay
91 | - Nimbus (~> 1.2.0)
92 | - NSAttributedStringMarkdownParser (~> 0.0.1)
93 | - NSStringEmojize
94 | - RTagCloudView
95 | - SDSegmentedControl
96 | - SSKeychain
97 |
98 | SPEC CHECKSUMS:
99 | AFNetworking: ae513199cca79e9d7af2708ccabe2ed075550c42
100 | fmemopen: 0c47f38f28a59216152d51fa80672c1549f80ea0
101 | HPGrowingTextView: 4318f557b33c19def1c53ec275d6e2a2d6589cd0
102 | LTUpdate: ee58a30f73e6dcbc47ce1e5c617b024212a2dd98
103 | MBProgressHUD: 2bbc6f470111daf7f3eaa4eb12b8cbf01c4c0622
104 | MTStatusBarOverlay: 2cee705996e4e307191d423bf49e583b9b2c14ac
105 | Nimbus: bbde56c7e845d3c38c1f484018ef1bb3259c0507
106 | NSAttributedStringMarkdownParser: fb93a47c4be94a80f4bd5e81dd8067cce5f7f5eb
107 | NSStringEmojize: ea303101d9174142813454c4f3616a1a569c1052
108 | RTagCloudView: 2c190afd8b633d908aba80b8f741403c004431be
109 | SDSegmentedControl: 165956a426f1fd7ff1eb486c4931241f12e0867e
110 | SSKeychain: 3d0b76c87e7b062a7ad1631a825fddec84367d44
111 |
112 | COCOAPODS: 0.32.1
113 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Ruby China社区和V2EX社区接口通用客户端
2 |
3 | [Ruby China](http://ruby-china.org/)社区接口,社区有:[Ruby China](http://ruby-china.org/)、[Tester Home](http://testerhome.com/)
4 |
5 | [V2EX](http://www.v2ex.com/)社区接口:[V2EX](http://www.v2ex.com/)
6 |
7 | ## 强烈提醒,勿随意发帖测试
8 | 请把玩这个客户端源码的同学,不要在上面几个社区上随意发帖测试,谢谢配合。
9 |
10 | ## THKS To Contributors
11 | [**luzhiyongGit**](https://github.com/luzhiyongGit) [**bachue**](https://github.com/bachue) [**gbammc**](https://github.com/gbammc)
12 |
13 | ##JLRubyChina-iPhone
14 | 希望能给上面几个社区活跃的同学带来一点帮助,节省一点时间。欢迎大家在使用过程中,提出改进建议和意见。同时期望更多的同学参与学习交流,维护和优化APP。
15 |
16 | ## 开发环境
17 | XCode5 iOS7.x & iOS6.x
18 |
19 | ## 编译安装
20 | 1、下载[最近的Release版本](https://github.com/jimneylee/JLRubyChina-iPhone/releases),直接编译即可安装。
21 |
22 | 2、fork后clone到本地,手工添加依赖库安装方法
23 | * 1、git submodule
24 |
25 | ``` bash
26 | $ git submodule init
27 | $ git submodule update
28 | ```
29 |
30 | * 2、[CocoaPods](http://cocoapods.org)
31 |
32 | ``` bash
33 | $ pod install
34 | ```
35 |
36 | 3、通过'JLRubyChina.xcworkspace'打开项目,也可以[自定义xopen命令](http://jimneylee.github.io/2014/01/09/add-xopen-command-to-open-xcode-workspace/)便捷打开
37 |
38 | 
39 |
40 | # ERROR解决方法
41 |
42 | 1、若出现这个问题:'vendor/JLNimbusTimeline' already exists in the index
43 | ``` bash
44 | $ git rm --cached vendor/JLNimbusTimeline
45 | ```
46 |
47 | 2、如果JLNimbusTimeline里面编译出错,`git submodule update`无法更新时,请删除JLNimbusTimeline重新添加,步骤如下:
48 |
49 | * 1、`.git/config`删除依赖JLNimbusTimeline相关,`vi .git/config`
50 | * 2、删除`.git/modules/vendor`下JLNimbusTimeline目录,`rm -rf .git/modules/vendor/JLNimbusTimeline`
51 | * 3、到工程vendor目录,删除JLNimbusTimeline,`rm -rf vendor/JLNimbusTimeline`
52 | * 4、删除`git submodule add`对应的cache,`git rm --cached vendor/JLNimbusTimeline`
53 | * 5、重新添加submodule,
54 | `git submodule add https://github.com/jimneylee/JLNimbusTimeline.git vendor/JLNimbusTimeline`
55 |
56 | 5、若出现这个问题:diff: /../Podfile.lock: No such file or directory
57 | diff: /Manifest.lock: No such file or directory
58 | error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
59 | ``` bash
60 | $ [sudo]pod install
61 | ```
62 |
63 | 6、若出现这个问题:library not found for -lPods
64 |
65 | 解决方法1、没有通过pod update生成的JLRubyChina.xcworkspace来打开工程
66 |
67 | 
68 |
69 | 解决方法2、Pods工程中,试着如下修改TARGETS的Pods,今天搞了一上午才解决这个错误问题
70 | 
71 |
72 | # 多个git server仓库同步
73 | 今天研究了多个git server仓库同步,把项目同步到[osc](http://git.oschina.net)和[gitcafe](https://gitcafe.com),不熟悉如何同步到多个git server,可以参考我的[这篇blog](http://jimneylee.github.io/2013/12/20/git-push-multi-server/),仓库地址分别如下
74 |
75 | github:https://github.com/jimneylee/JLRubyChina-iPhone
76 |
77 | gitcafe:https://gitcafe.com/jimneylee/JLRubyChina-iPhone
78 |
79 | oschina:http://git.oschina.net/jimneylee/JLRubyChina-iPhone
80 |
81 | csdn:https://code.csdn.net/jimney_ljj/JLRubyChina-iPhone
82 |
83 | 使用相同的ssh key,同步还是很方便的,后面考虑进一步精简步骤,自动化发布到各个git server
84 |
85 | ### DONE
86 | 1、首页热门帖子显示
87 |
88 | 2、帖子详细浏览、帖子回复列表
89 |
90 | 3、帖子关注、收藏、@某人
91 |
92 | 4、回复帖子支持表情选择
93 |
94 | 5、发帖到指定分类,支持markdown语法
95 |
96 | 6、分类节点列表查看
97 |
98 | 7、酷站分组显示
99 |
100 | 8、会员TOP N查看
101 |
102 | 9、我的主页,已发帖子、收藏帖子查看
103 |
104 | 10、Ruby China Wiki
105 |
106 | 11、更多功能包含:清空缓存、更新检测、给我评分、关于APP
107 |
108 | 12、帖子列表支持markdown语法解析显示(仅使用于7.x),效果不是太好
109 |
110 | 13、网络2G/3G/WIFI切换提示
111 |
112 | ## LICENSE
113 | 本项目基于MIT协议发布
114 | MIT: [http://rem.mit-license.org](http://rem.mit-license.org)
115 |
116 | # Screenshots
117 | 
118 | 
119 |
120 |
121 | 
122 | 
123 |
124 |
125 | 
126 | 
127 |
128 |
129 | 
130 | 
131 |
132 |
133 | 
134 | 
135 |
--------------------------------------------------------------------------------
/Resource/Images/Common/37x-Checkmark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/37x-Checkmark.png
--------------------------------------------------------------------------------
/Resource/Images/Common/37x-Checkmark@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/37x-Checkmark@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Common/QuickReply/MessageEntryBackground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/QuickReply/MessageEntryBackground.png
--------------------------------------------------------------------------------
/Resource/Images/Common/QuickReply/MessageEntryBackground@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/QuickReply/MessageEntryBackground@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Common/QuickReply/MessageEntryInputField.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/QuickReply/MessageEntryInputField.png
--------------------------------------------------------------------------------
/Resource/Images/Common/QuickReply/MessageEntryInputField@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/QuickReply/MessageEntryInputField@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Common/QuickReply/MessageEntrySendButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/QuickReply/MessageEntrySendButton.png
--------------------------------------------------------------------------------
/Resource/Images/Common/QuickReply/MessageEntrySendButton@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/QuickReply/MessageEntrySendButton@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Common/QuickReply/MessageEntrySendButtonPressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/QuickReply/MessageEntrySendButtonPressed.png
--------------------------------------------------------------------------------
/Resource/Images/Common/QuickReply/MessageEntrySendButtonPressed@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/QuickReply/MessageEntrySendButtonPressed@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Common/head_b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/head_b.png
--------------------------------------------------------------------------------
/Resource/Images/Common/head_b@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/head_b@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Common/head_s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/head_s.png
--------------------------------------------------------------------------------
/Resource/Images/Common/head_s@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/head_s@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Common/icon_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/icon_menu.png
--------------------------------------------------------------------------------
/Resource/Images/Common/icon_menu@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/icon_menu@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Common/more_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/more_photo.png
--------------------------------------------------------------------------------
/Resource/Images/Common/more_photo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Common/more_photo@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/Default-375w-667h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/Default-375w-667h@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/Default-414w-736h@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/Default-414w-736h@3x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/Default-568h@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/Default.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/Default@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/icon.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/icon/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/icon/icon.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/icon/icon120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/icon/icon120.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/icon/icon58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/icon/icon58.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/icon/icon80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/icon/icon80.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/icon/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/icon/icon@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/icon/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/icon/logo512.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/icon120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/icon120.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/icon512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/icon512.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/icon58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/icon58.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/icon80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/icon80.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/icon@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/pure_icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/pure_icon@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/ruby-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/ruby-logo.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/RubyChina/IconDefault/ruby-logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/RubyChina/IconDefault/ruby-logo@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/TesterHome/IconDefault/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/TesterHome/IconDefault/Default-568h@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/TesterHome/IconDefault/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/TesterHome/IconDefault/Default.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/TesterHome/IconDefault/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/TesterHome/IconDefault/Default@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/TesterHome/IconDefault/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/TesterHome/IconDefault/icon.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/TesterHome/IconDefault/icon120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/TesterHome/IconDefault/icon120.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/TesterHome/IconDefault/icon58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/TesterHome/IconDefault/icon58.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/TesterHome/IconDefault/icon80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/TesterHome/IconDefault/icon80.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/TesterHome/IconDefault/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/TesterHome/IconDefault/icon@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/TesterHome/IconDefault/ruby-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/TesterHome/IconDefault/ruby-logo.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/TesterHome/IconDefault/ruby-logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/TesterHome/IconDefault/ruby-logo@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/IconDefault/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/IconDefault/Default-568h@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/IconDefault/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/IconDefault/Default.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/IconDefault/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/IconDefault/Default@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/IconDefault/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/IconDefault/icon.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/IconDefault/icon120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/IconDefault/icon120.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/IconDefault/icon58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/IconDefault/icon58.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/IconDefault/icon80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/IconDefault/icon80.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/IconDefault/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/IconDefault/icon@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/IconDefault/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/IconDefault/logo.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/IconDefault/ruby-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/IconDefault/ruby-logo.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/IconDefault/ruby-logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/IconDefault/ruby-logo@2x.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/Screenshots/0110_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/Screenshots/0110_1.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/Screenshots/0110_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/Screenshots/0110_2.png
--------------------------------------------------------------------------------
/Resource/Images/Forums/V2EX/Screenshots/0110_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Images/Forums/V2EX/Screenshots/0110_3.png
--------------------------------------------------------------------------------
/Resource/Screenshots/ErrorResolve/not_found_pods.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Screenshots/ErrorResolve/not_found_pods.png
--------------------------------------------------------------------------------
/Resource/Screenshots/ErrorResolve/open_xcworkspace.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Screenshots/ErrorResolve/open_xcworkspace.jpg
--------------------------------------------------------------------------------
/Resource/Screenshots/default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Screenshots/default.png
--------------------------------------------------------------------------------
/Resource/Screenshots/home_activity_topics.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Screenshots/home_activity_topics.png
--------------------------------------------------------------------------------
/Resource/Screenshots/home_page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Screenshots/home_page.png
--------------------------------------------------------------------------------
/Resource/Screenshots/left_menu_side.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Screenshots/left_menu_side.png
--------------------------------------------------------------------------------
/Resource/Screenshots/more.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Screenshots/more.png
--------------------------------------------------------------------------------
/Resource/Screenshots/node_select.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Screenshots/node_select.png
--------------------------------------------------------------------------------
/Resource/Screenshots/nodes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Screenshots/nodes.png
--------------------------------------------------------------------------------
/Resource/Screenshots/outside_link_sites.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Screenshots/outside_link_sites.png
--------------------------------------------------------------------------------
/Resource/Screenshots/top_members.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Screenshots/top_members.png
--------------------------------------------------------------------------------
/Resource/Screenshots/topic_reply.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jimneylee/JLRubyChina-iPhone/bd60977fd3212e3f3713e9f0152cb4e94bcfb594/Resource/Screenshots/topic_reply.png
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 |
2 | #TODO
3 | 1、与后台API接口修改确认,参见API Problem文档说明
4 | 2、网络2G/3G/WIFI切换提示
5 | 3、发布模式下需屏蔽No Point分类
6 | 4、增加社交组件分享
7 | 5、经公测稳定,提交AppStore审核,方便大家下载使用
8 | 6、如果需要的话,添加友盟统计
9 |
10 | // Other
11 | pod push command:
12 | pod spec lint libname.podspec
13 | pod push libname.podspec
14 |
15 | git submodule add https://github.com/jimneylee/RTagCloudView.git vendor/RTagCloudView
16 | git rm -r --cached vendor/RTagCloudView
17 |
--------------------------------------------------------------------------------