├── .gitignore ├── LICENSE ├── Launch Screen.xib ├── Podfile ├── README.md ├── lists.txt ├── rssreader.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── rssreader.xccheckout │ └── xcuserdata │ │ ├── huwei.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── zhuchao.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── huwei.xcuserdatad │ └── xcschemes │ │ ├── rssreader.xcscheme │ │ └── xcschememanagement.plist │ └── zhuchao.xcuserdatad │ └── xcschemes │ ├── rssreader.xcscheme │ └── xcschememanagement.plist └── rssreader ├── AppDelegate.h ├── AppDelegate.m ├── Aspect-Appearance.m ├── Aspect-Config.m ├── Aspect-Font.m ├── Aspect-UMengConfig.m ├── Aspect-Window.m ├── Home ├── Config.h ├── Config.m ├── Data │ ├── DataCenter.h │ ├── DataCenter.m │ ├── UserCenter.h │ └── UserCenter.m ├── Model │ ├── FeedEntity.h │ ├── FeedEntity.m │ ├── FeedList.h │ ├── FeedList.m │ ├── FeedRssEntity.h │ ├── FeedRssEntity.m │ ├── RssEntity.h │ ├── RssEntity.m │ ├── RssList.h │ └── RssList.m ├── Request │ ├── AddFeedRequest.h │ ├── AddFeedRequest.m │ ├── ChannelRequest.h │ ├── ChannelRequest.m │ ├── DeleteSubscribeRequest.h │ ├── DeleteSubscribeRequest.m │ ├── FeedListRequest.h │ ├── FeedListRequest.m │ ├── RecommendRequest.h │ ├── RecommendRequest.m │ ├── RssListRequest.h │ ├── RssListRequest.m │ ├── SearchWeChatRequest.h │ ├── SearchWeChatRequest.m │ ├── SubsucribeTopicRequest.h │ ├── SubsucribeTopicRequest.m │ ├── TagListRequest.h │ ├── TagListRequest.m │ ├── TopicDetailRequest.h │ ├── TopicDetailRequest.m │ ├── TopicRecommendRequest.h │ └── TopicRecommendRequest.m ├── Rescource │ ├── Default-568h.png │ ├── Default.png │ ├── Default@2x.png │ ├── XinGothic.otf │ ├── bg.jpg │ ├── html │ │ ├── detail.html │ │ ├── page_mp_article_improve236317.css │ │ └── page_mp_article_improve_combo238f07.css │ ├── icon.png │ ├── icon@2x.png │ └── rssIcon@2x.png ├── Scene │ ├── Base │ │ ├── BaseScene.h │ │ └── BaseScene.m │ ├── ChannelScene.h │ ├── ChannelScene.m │ ├── ChannelTableView.h │ ├── ChannelTableView.m │ ├── EzUILabel.h │ ├── EzUILabel.m │ ├── Main │ │ ├── AddScene.h │ │ ├── AddScene.m │ │ ├── FavScene.h │ │ ├── FavScene.m │ │ ├── FeedCell.h │ │ ├── FeedCell.m │ │ ├── RssCell.h │ │ ├── RssCell.m │ │ ├── RssDetailScene.h │ │ ├── RssDetailScene.m │ │ ├── RssListScene.h │ │ ├── RssListScene.m │ │ ├── SquareScene.h │ │ ├── SquareScene.m │ │ ├── WeChatListScene.h │ │ └── WeChatListScene.m │ ├── MineScene.h │ ├── MineScene.m │ ├── RDNavigationController.h │ ├── RDNavigationController.m │ ├── SettingScene.h │ ├── SettingScene.m │ ├── SquareFooter.h │ ├── SquareFooter.m │ ├── SquareHeader.h │ ├── SquareHeader.m │ ├── SquareTableView.h │ ├── SquareTableView.m │ ├── TabBarController.h │ ├── TabBarController.m │ ├── TopicCell.h │ ├── TopicCell.m │ ├── TopicListScene.h │ ├── TopicListScene.m │ ├── TopicScene.h │ ├── TopicScene.m │ ├── WebDetailScene.h │ └── WebDetailScene.m ├── SceneModel │ ├── ActionSceneModel.h │ ├── ActionSceneModel.m │ ├── ChannelSceneModel.h │ ├── ChannelSceneModel.m │ ├── DiscoverySceneModel.h │ ├── DiscoverySceneModel.m │ ├── FavSceneModel.h │ ├── FavSceneModel.m │ ├── FeedSceneModel.h │ ├── FeedSceneModel.m │ ├── RecommendSceneModel.h │ ├── RecommendSceneModel.m │ ├── RssListSceneModel.h │ ├── RssListSceneModel.m │ ├── TopicListSceneModel.h │ ├── TopicListSceneModel.m │ ├── TopicSceneModel.h │ ├── TopicSceneModel.m │ ├── WeChatSceneModel.h │ └── WeChatSceneModel.m ├── UIColor+RSS.h ├── UIColor+RSS.m ├── UIImageView+Network.h ├── UIImageView+Network.m └── URLManage.plist ├── Images.xcassets ├── AppIcon.appiconset │ └── Contents.json └── LaunchImage.launchimage │ └── Contents.json └── Supporting Files ├── Info.plist ├── PrefixHeader.pch └── main.m /.gitignore: -------------------------------------------------------------------------------- 1 | Pods/ 2 | Podfile.lock 3 | .DS_Store 4 | rssreader.xcworkspace -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | EasyRSS based on EasyIOS 294 | Copyright (c) 2014 zhuchaowe 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /Launch Screen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '7.0' 2 | target "rssreader" do 3 | pod 'EasyIOS', :git=>'https://github.com/zhuchaowe/EasyIOS.git', :tag => '2.2.3' 4 | pod 'EasyIOS-Extention', '~> 1.2' 5 | pod 'UIColor+MLPFlatColors', '~> 1.0' 6 | pod 'UMengAnalytics', '~> 3.1.2' 7 | pod 'TOWebViewController', '~> 2.0.13' 8 | pod 'SWTableViewCell', '~> 0.3.7' 9 | pod 'HTHorizontalSelectionList', '~> 0.3.1' 10 | end 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | EasyRSS 2 | ======= 3 | 4 | EasyRSS is a rss reader for ios based on EasyIOS 2.2.2 5 | 6 | [EasyIOS 2.2.2](https://github.com/zhuchaowe/EasyIOS) 7 | 8 | ![image](https://raw.githubusercontent.com/zhuchaowe/EasyRSS/master/rssreader/Home/Rescource/Default.png) 9 | 10 | 下载后请`pod update` 11 | 12 | ##DEMO 13 | * 1.计划在业余时间利用EasyIOS开发一个开源RSS阅读器。 14 | * 2.做为EasyIOS的demo,方便大家学习EasyIOS。 15 | * 3.如果你有兴趣,可以在qq群[340906744](http://shang.qq.com/wpa/qunwpa?idkey=562d002e275a8199081313b00580fb7111a4faf694216a239064d29f5238bc91) 联系到我,一起完成。 16 | * 4.本项目持续更新 17 | 18 | ##TODO 19 | 20 | * 1.增加rss推荐 21 | * 2.增加rss分享到发现 22 | * 3.增加收藏操作 23 | * 4.增加缓存清理 24 | * 5.增加rss保存时间 25 | * 6.修改首页排版 26 | * 7.修改刷新hud交互 27 | 28 | 29 | 30 | #LICENSE 31 | * EasyRSS遵循GPL协议 32 | 33 | 34 | GNU GENERAL PUBLIC LICENSE 35 | Version 2, June 1991 36 | 37 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 38 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 39 | Everyone is permitted to copy and distribute verbatim copies 40 | of this license document, but changing it is not allowed. 41 | -------------------------------------------------------------------------------- /lists.txt: -------------------------------------------------------------------------------- 1 | { 2 | "list":[ 3 | {"url":"http://easyios.08dream.com/index.php?s=/Home/Index/docRss","name":"EasyIOS梦享社区-资讯"}, 4 | {"url":"http://www.oschina.net/news/rss","name":"oschina新闻资讯"}, 5 | {"url":"http://zuimeia.com/feed/","name":"最美应用"}, 6 | {"url":"http://appdp.com/feed/","name":"APP每日推送"}, 7 | {"url":"http://www.oschina.net/translate/rss?type=2","name":"oschina翻译技术文章"}, 8 | {"url":"http://feed.feedsky.com/qiushi","name":"糗事百科"}, 9 | {"url":"http://feed.xiaohuayoumo.com/","name":"幽默笑话百分百,只有笑话的网站"}, 10 | {"url":"http://jandan.net/feed","name":"煎蛋"}, 11 | {"url":"http://www.36kr.com/feed","name":"36氪|关注互联网创业"}, 12 | {"url":"http://www.techwom.com/rss","name":"科技娲母-最有用的互联网相关文章"}, 13 | {"url":"http://www.zhihu.com/rss","name":"知乎日报精选"}, 14 | {"url":"http://www.alibuybuy.com/feed","name":"互联网的那点事"}, 15 | {"url":"http://www.guokr.com/rss/","name":"果壳网"}, 16 | {"url":"http://www.baisibudejie.com/feed","name":"百思不得姐"}, 17 | {"url":"http://feed.iplaysoft.com/","name":"异次元软件世界"}, 18 | {"url":"http://cn.engadget.com/rss.xml","name":"Engadget 中国版 RSS Feed"}, 19 | {"url":"http://www.u148.net/rss/","name":"有意思吧"}, 20 | {"url":"http://blog.devtang.com/atom.xml","name":"唐巧的技术博客"}, 21 | {"url":"http://www.mifengtd.cn/feed","name":"褪墨・时间管理,个人提升,生活健康与习惯"}, 22 | {"url":"http://www.chong4.com.cn/feed.php","name":"穿衣打扮|提供服饰搭配,美容知识"}, 23 | {"url":"http://feeds.juetuzhi.cn/","name":"掘图志|分享视频与图片的乐趣。"}, 24 | {"url":"http://songshuhui.net/feed","name":"科学松鼠会"}, 25 | {"url":"http://appshopper.com/feed/?mode=featured&filter=price&type=free","name":"AppShopper.com|ios限时免费"} 26 | ] 27 | } -------------------------------------------------------------------------------- /rssreader.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /rssreader.xcodeproj/project.xcworkspace/xcshareddata/rssreader.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 50AD1DAF-8B71-4CA8-AC77-071FD740A14E 9 | IDESourceControlProjectName 10 | rssreader 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 0E9EE53C9050AE99CC5FE165250627BF5A2C2782 14 | https://github.com/zhuchaowe/EasyRSS.git 15 | 16 | IDESourceControlProjectPath 17 | rssreader.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 0E9EE53C9050AE99CC5FE165250627BF5A2C2782 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/zhuchaowe/EasyRSS.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 0E9EE53C9050AE99CC5FE165250627BF5A2C2782 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 0E9EE53C9050AE99CC5FE165250627BF5A2C2782 36 | IDESourceControlWCCName 37 | EasyRSS 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /rssreader.xcodeproj/project.xcworkspace/xcuserdata/huwei.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuchaowe/EasyRSS/59c588577139bc289d581a47d7b7ca52d5d7b2e2/rssreader.xcodeproj/project.xcworkspace/xcuserdata/huwei.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /rssreader.xcodeproj/project.xcworkspace/xcuserdata/zhuchao.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuchaowe/EasyRSS/59c588577139bc289d581a47d7b7ca52d5d7b2e2/rssreader.xcodeproj/project.xcworkspace/xcuserdata/zhuchao.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /rssreader.xcodeproj/xcuserdata/huwei.xcuserdatad/xcschemes/rssreader.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /rssreader.xcodeproj/xcuserdata/huwei.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | rssreader.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 5F57827D199A43D600FCA0EE 16 | 17 | primary 18 | 19 | 20 | 5F578293199A43D700FCA0EE 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /rssreader.xcodeproj/xcuserdata/zhuchao.xcuserdatad/xcschemes/rssreader.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | 97 | 99 | 105 | 106 | 107 | 108 | 110 | 111 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /rssreader.xcodeproj/xcuserdata/zhuchao.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | rssreader.xcscheme 8 | 9 | orderHint 10 | 18 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 5F57827D199A43D600FCA0EE 16 | 17 | primary 18 | 19 | 20 | 5F578293199A43D700FCA0EE 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /rssreader/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-12. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDatabase.h" 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | @property(strong,nonatomic)AppDatabase *database; 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /rssreader/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-12. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "MobClick.h" 11 | #import "RssEntity.h" 12 | #import "DataCenter.h" 13 | #import "RDNavigationController.h" 14 | 15 | @interface AppDelegate () 16 | @end 17 | 18 | @implementation AppDelegate 19 | 20 | 21 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 22 | 23 | // IOS8 新系统需要使用新的代码咯 24 | if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) 25 | { 26 | [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings 27 | settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) 28 | categories:nil]]; 29 | 30 | 31 | [[UIApplication sharedApplication] registerForRemoteNotifications]; 32 | } 33 | else 34 | { 35 | //这里还是原来的代码 36 | [[UIApplication sharedApplication] registerForRemoteNotificationTypes: 37 | (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)]; 38 | } 39 | 40 | UILocalNotification * notification=[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; 41 | if(notification !=nil && [notification.userInfo objectForKey:@"time"]){ 42 | [DataCenter sharedInstance].time = [notification.userInfo objectForKey:@"time"]; 43 | } 44 | [self setUpBackGroundReflash]; 45 | 46 | return YES; 47 | } 48 | 49 | - (void)applicationWillResignActive:(UIApplication *)application { 50 | // [Rss setUpNoti]; 51 | } 52 | 53 | - (void)applicationDidEnterBackground:(UIApplication *)application { 54 | 55 | } 56 | 57 | - (void)applicationWillEnterForeground:(UIApplication *)application { 58 | 59 | } 60 | 61 | - (void)applicationDidBecomeActive:(UIApplication *)application { 62 | [[UIApplication sharedApplication] cancelAllLocalNotifications]; 63 | } 64 | 65 | - (void)applicationWillTerminate:(UIApplication *)application { 66 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 67 | } 68 | 69 | //-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{ 70 | // if([notification.userInfo objectForKey:@"time"]){ 71 | // [DataCenter sharedInstance].time = [notification.userInfo objectForKey:@"time"]; 72 | // PresentRssList *presentRssListScene = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"PresentRssList"]; 73 | // RDNavigationController *nav = [[RDNavigationController alloc]initWithRootViewController:presentRssListScene]; 74 | // [_rootScene presentViewController:nav animated:YES completion:nil]; 75 | // } 76 | //} 77 | 78 | //- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{ 79 | // NSLog(@"%@", [url absoluteString]); 80 | // if ([url.scheme isEqualToString:@"feed"]) { 81 | // AddScene *addScene = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"AddScene"]; 82 | // 83 | // CenterNav *centerNav = [[CenterNav alloc]initWithRootViewController:addScene]; 84 | // [_rootScene presentViewController:centerNav animated:YES completion:nil]; 85 | // } 86 | // 87 | // return YES; 88 | //} 89 | 90 | - (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler{ 91 | 92 | [[$ rac_didNetworkChanges] 93 | subscribeNext:^(NSNumber *status) { 94 | AFNetworkReachabilityStatus networkStatus = [status intValue]; 95 | switch (networkStatus) { 96 | case AFNetworkReachabilityStatusUnknown: 97 | case AFNetworkReachabilityStatusNotReachable: 98 | case AFNetworkReachabilityStatusReachableViaWWAN: 99 | [DataCenter sharedInstance].isWifi = NO; 100 | completionHandler(UIBackgroundFetchResultNoData); 101 | break; 102 | case AFNetworkReachabilityStatusReachableViaWiFi: 103 | [DataCenter sharedInstance].isWifi = YES; 104 | completionHandler(UIBackgroundFetchResultNoData); 105 | // [[FeedSceneModel sharedInstance] 106 | // reflashAllFeed:nil each:nil finish:^{ 107 | // if([Rss notifyNewMessage]){ 108 | // completionHandler(UIBackgroundFetchResultNewData); 109 | // }else{ 110 | // completionHandler(UIBackgroundFetchResultNoData); 111 | // } 112 | // }]; 113 | break; 114 | } 115 | }]; 116 | } 117 | 118 | 119 | -(void)setUpBackGroundReflash{ 120 | [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:1800]; 121 | } 122 | 123 | 124 | @end 125 | -------------------------------------------------------------------------------- /rssreader/Aspect-Appearance.m: -------------------------------------------------------------------------------- 1 | // 2 | // Aspect-appearance.m 3 | // mcapp 4 | // 5 | // Created by zhuchao on 14/12/16. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import 11 | 12 | 13 | #define AtAspect Appearance 14 | 15 | #define AtAspectOfClass AppDelegate 16 | @classPatchField(AppDelegate) 17 | AspectPatch(-, BOOL, application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions) 18 | { 19 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; 20 | [[UINavigationBar appearance] setBarTintColor:[UIColor flatDarkOrangeColor]]; 21 | [[UINavigationBar appearance] setTintColor:[UIColor whiteColor]]; 22 | 23 | [[UITabBar appearance] setTintColor:[UIColor flatDarkOrangeColor]]; 24 | [[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: 25 | [UIColor whiteColor],NSForegroundColorAttributeName, 26 | [UIFont systemFontOfSize:18],NSFontAttributeName, 27 | nil]]; 28 | 29 | return XAMessageForward(application:application didFinishLaunchingWithOptions:launchOptions); 30 | } 31 | @end 32 | #undef AtAspectOfClass 33 | #undef AtAspect -------------------------------------------------------------------------------- /rssreader/Aspect-Config.m: -------------------------------------------------------------------------------- 1 | // 2 | // Aspect-Config.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/18. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import 11 | 12 | #define AtAspect Config 13 | 14 | #define AtAspectOfClass AppDelegate 15 | @classPatchField(AppDelegate) 16 | 17 | AspectPatch(-, BOOL, application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions) { 18 | 19 | NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"URLManage" ofType:@"plist"]; 20 | [URLManager loadConfigFromPlist:plistPath]; 21 | 22 | return XAMessageForward(application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions); 23 | 24 | } 25 | @end 26 | #undef AtAspectOfClass 27 | 28 | #undef AtAspect 29 | -------------------------------------------------------------------------------- /rssreader/Aspect-Font.m: -------------------------------------------------------------------------------- 1 | // 2 | // Aspect-appearance.m 3 | // mcapp 4 | // 5 | // Created by zhuchao on 14/12/16. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import 11 | 12 | 13 | #define AtAspect Font 14 | 15 | #define AtAspectOfClass AppDelegate 16 | @classPatchField(AppDelegate) 17 | AspectPatch(-, BOOL, application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions) 18 | { 19 | [IconFont loadFontList]; 20 | [IconFont registerFontWithDict:@{@"ttf":@"XinGothic.otf"}]; 21 | 22 | return XAMessageForward(application:application didFinishLaunchingWithOptions:launchOptions); 23 | } 24 | @end 25 | #undef AtAspectOfClass 26 | #undef AtAspect -------------------------------------------------------------------------------- /rssreader/Aspect-UMengConfig.m: -------------------------------------------------------------------------------- 1 | // 2 | // Aspect-appearance.m 3 | // mcapp 4 | // 5 | // Created by zhuchao on 14/12/16. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import 11 | #import "MobClick.h" 12 | 13 | #define CHANNEL_ID @"pgyer" 14 | #define UMAppKey @"53f8902ffd98c585ba02a156" 15 | #define AtAspect UMengConfig 16 | 17 | #define AtAspectOfClass AppDelegate 18 | @classPatchField(AppDelegate) 19 | AspectPatch(-, BOOL, application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions) 20 | { 21 | 22 | [MobClick startWithAppkey:UMAppKey reportPolicy:SEND_INTERVAL channelId:CHANNEL_ID]; 23 | [MobClick checkUpdate]; 24 | 25 | return XAMessageForward(application:application didFinishLaunchingWithOptions:launchOptions); 26 | } 27 | 28 | @end 29 | #undef AtAspectOfClass 30 | #undef AtAspect -------------------------------------------------------------------------------- /rssreader/Aspect-Window.m: -------------------------------------------------------------------------------- 1 | // 2 | // Aspect-Window.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/14. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import 11 | #import "TabBarController.h" 12 | #import "DataCenter.h" 13 | 14 | #define AtAspect Window 15 | 16 | #define AtAspectOfClass AppDelegate 17 | @classPatchField(AppDelegate) 18 | 19 | AspectPatch(-, void,application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions) { 20 | 21 | self.database = [[AppDatabase alloc]initWithMigrations]; 22 | 23 | [Action actionConfigHost:@"rss.iosx.me" client:@"easyios" codeKey:@"Code" rightCode:0 msgKey:@"Msg"]; 24 | 25 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 26 | self.window.backgroundColor = [UIColor blackColor]; 27 | 28 | TabBarController *centerNav = [[TabBarController alloc]init]; 29 | 30 | self.window.rootViewController = centerNav; 31 | [self.window makeKeyAndVisible]; 32 | 33 | [[$ rac_didNetworkChanges] 34 | subscribeNext:^(NSNumber *status) { 35 | AFNetworkReachabilityStatus networkStatus = [status intValue]; 36 | switch (networkStatus) { 37 | case AFNetworkReachabilityStatusUnknown: 38 | case AFNetworkReachabilityStatusNotReachable: 39 | [DataCenter sharedInstance].isWifi = NO; 40 | [[DialogUtil sharedInstance] showDlg:self.window textOnly:@"网络连接不给力"]; 41 | break; 42 | case AFNetworkReachabilityStatusReachableViaWWAN: 43 | [DataCenter sharedInstance].isWifi = NO; 44 | [[DialogUtil sharedInstance] showDlg:self.window textOnly:@"当前使用移动数据网络"]; 45 | break; 46 | case AFNetworkReachabilityStatusReachableViaWiFi: 47 | [DataCenter sharedInstance].isWifi = YES; 48 | break; 49 | } 50 | }]; 51 | 52 | 53 | XAMessageForward(application:application didFinishLaunchingWithOptions:launchOptions); 54 | } 55 | @end 56 | #undef AtAspectOfClass 57 | 58 | #undef AtAspect 59 | -------------------------------------------------------------------------------- /rssreader/Home/Config.h: -------------------------------------------------------------------------------- 1 | // 2 | // Config.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/18. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface Config : NSObject 12 | @property(nonatomic,retain)NSNumber *noImageMode; 13 | @property(nonatomic,retain)NSNumber *nightMode; 14 | 15 | AS_SINGLETON(Config) 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /rssreader/Home/Config.m: -------------------------------------------------------------------------------- 1 | // 2 | // Config.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/18. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Config.h" 10 | 11 | @implementation Config 12 | 13 | DEF_SINGLETON(Config) 14 | 15 | -(instancetype)init{ 16 | self = [super init]; 17 | if(self){ 18 | [$ touchPath:$.libPrePath]; 19 | NSString *configPath = [$.libPrePath stringByAppendingPathComponent:@"config.plist"]; 20 | [$ touchFile:configPath]; 21 | NSMutableDictionary *config = [NSMutableDictionary dictionaryWithContentsOfFile:configPath]; 22 | if(!config.isNotEmpty){ 23 | config = [NSMutableDictionary dictionary]; 24 | [config setValue:[NSNumber numberWithBool:NO] forKey:@"noImageMode"]; 25 | [config setValue:[NSNumber numberWithBool:NO] forKey:@"nightMode"]; 26 | [config writeToFile:configPath atomically:YES]; 27 | } 28 | } 29 | return self; 30 | } 31 | 32 | -(void)setNoImageMode:(NSNumber *)noImageMode{ 33 | [self saveValue:noImageMode forKey:@"noImageMode"]; 34 | } 35 | 36 | -(NSNumber *)noImageMode{ 37 | return [self getValueForKey:@"noImageMode"]; 38 | } 39 | 40 | -(void)setNightMode:(NSNumber *)nightMode{ 41 | [self saveValue:nightMode forKey:@"nightMode"]; 42 | } 43 | 44 | -(NSNumber *)nightMode{ 45 | return [self getValueForKey:@"nightMode"]; 46 | } 47 | 48 | -(void)saveValue:(id)value forKey:(NSString *)key{ 49 | NSString *configPath = [$.libPrePath stringByAppendingPathComponent:@"config.plist"]; 50 | NSMutableDictionary *config = [NSMutableDictionary dictionaryWithContentsOfFile:configPath]; 51 | [config setValue:value forKey:key]; 52 | [config writeToFile:configPath atomically:YES]; 53 | } 54 | 55 | -(id)getValueForKey:(NSString *)key{ 56 | NSString *configPath = [$.libPrePath stringByAppendingPathComponent:@"config.plist"]; 57 | NSMutableDictionary *config = [NSMutableDictionary dictionaryWithContentsOfFile:configPath]; 58 | return [config objectForKey:key]; 59 | } 60 | @end 61 | -------------------------------------------------------------------------------- /rssreader/Home/Data/DataCenter.h: -------------------------------------------------------------------------------- 1 | // 2 | // DataCenter.h 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-27. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DataCenter : NSObject 12 | @property(nonatomic,retain)NSString *time; 13 | @property(nonatomic,assign)BOOL isWifi; 14 | @property(nonatomic,retain)NSMutableDictionary *config; 15 | 16 | /** 17 | * 生成单例 18 | * 19 | * @return instancetype FeedSceneModel单例 20 | */ 21 | + (instancetype)sharedInstance; 22 | @end 23 | -------------------------------------------------------------------------------- /rssreader/Home/Data/DataCenter.m: -------------------------------------------------------------------------------- 1 | // 2 | // DataCenter.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-27. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "DataCenter.h" 10 | 11 | @implementation DataCenter 12 | 13 | /** 14 | * 生成单例 15 | * 16 | * @return FeedSceneModel单例 17 | */ 18 | + (instancetype)sharedInstance { 19 | GCDSharedInstance(^{ return [[self alloc] init]; }); 20 | } 21 | 22 | -(instancetype)init{ 23 | self = [super init]; 24 | if(self){ 25 | self.time = @""; 26 | self.isWifi = NO; 27 | } 28 | return self; 29 | } 30 | @end 31 | -------------------------------------------------------------------------------- /rssreader/Home/Data/UserCenter.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserCenter.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/7. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UserCenter : NSObject 12 | AS_SINGLETON(UserCenter) 13 | @property(nonatomic,retain)NSString *token; 14 | @end 15 | -------------------------------------------------------------------------------- /rssreader/Home/Data/UserCenter.m: -------------------------------------------------------------------------------- 1 | // 2 | // UserCenter.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/7. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "UserCenter.h" 10 | 11 | @implementation UserCenter 12 | DEF_SINGLETON(UserCenter) 13 | 14 | -(instancetype)init{ 15 | self = [super init]; 16 | if(self){ 17 | self.token = @"123456"; 18 | } 19 | return self; 20 | } 21 | @end 22 | -------------------------------------------------------------------------------- /rssreader/Home/Model/FeedEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // FeedEntity.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Model.h" 10 | 11 | @interface FeedEntity : Model 12 | @property(nonatomic,strong)NSString *favicon; 13 | @property(nonatomic,strong)NSNumber *feedId; 14 | @property(nonatomic,strong)NSString *link; 15 | @property(nonatomic,strong)NSString *summary; 16 | @property(nonatomic,strong)NSString *title; 17 | @property(nonatomic,strong)NSNumber *feedType; 18 | @property(nonatomic,strong)NSString *openUrl; 19 | @end 20 | 21 | @protocol FeedEntity 22 | @end -------------------------------------------------------------------------------- /rssreader/Home/Model/FeedEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // FeedEntity.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "FeedEntity.h" 10 | 11 | @implementation FeedEntity 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Model/FeedList.h: -------------------------------------------------------------------------------- 1 | // 2 | // FeedList.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Model.h" 10 | #import "Pagination.h" 11 | #import "FeedEntity.h" 12 | 13 | @interface FeedList : Model 14 | @property(nonatomic,strong)NSMutableArray *list; 15 | @property(nonatomic,strong)Pagination *pagination; 16 | @end 17 | -------------------------------------------------------------------------------- /rssreader/Home/Model/FeedList.m: -------------------------------------------------------------------------------- 1 | // 2 | // FeedList.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "FeedList.h" 10 | 11 | @implementation FeedList 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Model/FeedRssEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // FeedRssEntity.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/8. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Model.h" 10 | #import "RssEntity.h" 11 | #import "FeedEntity.h" 12 | @interface FeedRssEntity : Model 13 | @property(nonatomic,retain)RssEntity *rss; 14 | @property(nonatomic,retain)FeedEntity *feed; 15 | @end 16 | @protocol FeedRssEntity 17 | @end -------------------------------------------------------------------------------- /rssreader/Home/Model/FeedRssEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // FeedRssEntity.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/8. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "FeedRssEntity.h" 10 | 11 | @implementation FeedRssEntity 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Model/RssEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // RssEntity.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Model.h" 10 | #import "FeedEntity.h" 11 | 12 | @interface RssEntity : Model 13 | 14 | @property(nonatomic,strong)NSString *title; 15 | @property(nonatomic,strong)NSString *author; 16 | @property(nonatomic,strong)NSString *content; 17 | @property(nonatomic,strong)NSString *date; 18 | @property(nonatomic,strong)NSString *image; 19 | @property(nonatomic,strong)NSString *link; 20 | @property(nonatomic,strong)NSString *summary; 21 | @end 22 | 23 | 24 | @protocol RssEntity 25 | @end -------------------------------------------------------------------------------- /rssreader/Home/Model/RssEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // RssEntity.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "RssEntity.h" 10 | 11 | @implementation RssEntity 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Model/RssList.h: -------------------------------------------------------------------------------- 1 | // 2 | // RssList.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Model.h" 10 | #import "FeedRssEntity.h" 11 | #import "Pagination.h" 12 | 13 | @interface RssList : Model 14 | @property(nonatomic,strong)NSMutableArray *list; 15 | @property(nonatomic,strong)Pagination *pagination; 16 | @end 17 | -------------------------------------------------------------------------------- /rssreader/Home/Model/RssList.m: -------------------------------------------------------------------------------- 1 | // 2 | // RssList.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "RssList.h" 10 | 11 | @implementation RssList 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Request/AddFeedRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // AddFeedRequest.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Request.h" 10 | 11 | @interface AddFeedRequest : Request 12 | @property(nonatomic,retain)NSString *feedUrl; 13 | @property(nonatomic,retain)NSNumber *feedType; 14 | @end 15 | -------------------------------------------------------------------------------- /rssreader/Home/Request/AddFeedRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // AddFeedRequest.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "AddFeedRequest.h" 10 | #import "UserCenter.h" 11 | @implementation AddFeedRequest 12 | -(void)loadRequest{ 13 | [super loadRequest]; 14 | self.PATH = @"/addFeed"; 15 | self.METHOD = @"POST"; 16 | self.feedUrl = @""; 17 | self.feedType = @0; 18 | self.httpHeaderFields = @{@"M-API-KEY":[UserCenter sharedInstance].token}; 19 | } 20 | @end 21 | -------------------------------------------------------------------------------- /rssreader/Home/Request/ChannelRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // ChannelRequest.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/9. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Request.h" 10 | 11 | @interface ChannelRequest : Request 12 | @property(nonatomic,strong) NSNumber *pageSize; 13 | @property(nonatomic,strong) NSNumber *page; 14 | @property(nonatomic,strong) NSString *tagName; 15 | @end 16 | -------------------------------------------------------------------------------- /rssreader/Home/Request/ChannelRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // ChannelRequest.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/9. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "ChannelRequest.h" 10 | 11 | @implementation ChannelRequest 12 | -(void)loadRequest{ 13 | [super loadRequest]; 14 | self.PATH = @"/channelRecommend"; 15 | self.METHOD = @"POST"; 16 | self.pageSize = DEFAULT_PAGE_SIZE; 17 | self.page = @1; 18 | self.tagName = @"推荐"; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /rssreader/Home/Request/DeleteSubscribeRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // DeleteSubscribeRequest.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/10. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Request.h" 10 | 11 | @interface DeleteSubscribeRequest : Request 12 | @property(nonatomic,retain)NSNumber *feedId; 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Request/DeleteSubscribeRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // DeleteSubscribeRequest.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/10. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "DeleteSubscribeRequest.h" 10 | #import "UserCenter.h" 11 | 12 | @implementation DeleteSubscribeRequest 13 | 14 | -(void)loadRequest{ 15 | [super loadRequest]; 16 | self.PATH = @"/deleteSubscribe"; 17 | self.METHOD = @"POST"; 18 | self.feedId = @0; 19 | self.httpHeaderFields = @{@"M-API-KEY":[UserCenter sharedInstance].token}; 20 | } 21 | @end 22 | -------------------------------------------------------------------------------- /rssreader/Home/Request/FeedListRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // FeedListRequest.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Request.h" 10 | 11 | @interface FeedListRequest : Request 12 | @property(nonatomic,strong) NSNumber *pageSize; 13 | @property(nonatomic,strong) NSNumber *page; 14 | @end 15 | -------------------------------------------------------------------------------- /rssreader/Home/Request/FeedListRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // FeedListRequest.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "FeedListRequest.h" 10 | #import "UserCenter.h" 11 | 12 | @implementation FeedListRequest 13 | 14 | -(void)loadRequest{ 15 | [super loadRequest]; 16 | self.PATH = @"/feeds"; 17 | self.METHOD = @"GET"; 18 | self.pageSize = DEFAULT_PAGE_SIZE; 19 | self.page = @1; 20 | self.httpHeaderFields = @{@"M-API-KEY":[UserCenter sharedInstance].token}; 21 | 22 | } 23 | 24 | -(NSString *)pathInfo{ 25 | return @"/{page}/{pageSize}"; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /rssreader/Home/Request/RecommendRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // RecommendRequest.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/8. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Request.h" 10 | 11 | @interface RecommendRequest : Request 12 | @property(nonatomic,strong) NSNumber *pageSize; 13 | @property(nonatomic,strong) NSNumber *page; 14 | @property(nonatomic,strong) NSString *tagName; 15 | @end 16 | -------------------------------------------------------------------------------- /rssreader/Home/Request/RecommendRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // RecommendRequest.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/8. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "RecommendRequest.h" 10 | 11 | @implementation RecommendRequest 12 | -(void)loadRequest{ 13 | [super loadRequest]; 14 | self.PATH = @"/recommend"; 15 | self.METHOD = @"POST"; 16 | self.pageSize = DEFAULT_PAGE_SIZE; 17 | self.page = @1; 18 | self.tagName = @"推荐"; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /rssreader/Home/Request/RssListRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // RssListRequest.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Request.h" 10 | 11 | @interface RssListRequest : Request 12 | @property(nonatomic,strong) NSNumber *feedId; 13 | @property(nonatomic,strong) NSNumber *pageSize; 14 | @property(nonatomic,strong) NSNumber *page; 15 | @end 16 | -------------------------------------------------------------------------------- /rssreader/Home/Request/RssListRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // RssListRequest.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "RssListRequest.h" 10 | @implementation RssListRequest 11 | -(void)loadRequest{ 12 | [super loadRequest]; 13 | self.PATH = @"/rss"; 14 | self.METHOD = @"GET"; 15 | self.pageSize = DEFAULT_PAGE_SIZE; 16 | self.page = @1; 17 | self.feedId = @0; 18 | 19 | } 20 | 21 | -(NSString *)pathInfo{ 22 | return @"/{feedId}/{page}/{pageSize}"; 23 | } 24 | @end 25 | -------------------------------------------------------------------------------- /rssreader/Home/Request/SearchWeChatRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // SearchWeChatRequest.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/5. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Request.h" 10 | 11 | @interface SearchWeChatRequest : Request 12 | @property(nonatomic,retain)NSString *query; 13 | @property(nonatomic,retain)NSNumber *page; 14 | @end 15 | -------------------------------------------------------------------------------- /rssreader/Home/Request/SearchWeChatRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // SearchWeChatRequest.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/5. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SearchWeChatRequest.h" 10 | #import "UserCenter.h" 11 | 12 | @implementation SearchWeChatRequest 13 | -(void)loadRequest{ 14 | [super loadRequest]; 15 | self.PATH = @"/searchWeChat"; 16 | self.METHOD = @"POST"; 17 | self.page = @1; 18 | self.query = @""; 19 | 20 | self.httpHeaderFields = @{@"M-API-KEY":[UserCenter sharedInstance].token}; 21 | } 22 | @end 23 | -------------------------------------------------------------------------------- /rssreader/Home/Request/SubsucribeTopicRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // SubsucribeTopicRequest.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/15. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Request.h" 10 | 11 | @interface SubsucribeTopicRequest : Request 12 | @property(nonatomic,strong) NSString *title; 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Request/SubsucribeTopicRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // SubsucribeTopicRequest.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/15. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SubsucribeTopicRequest.h" 10 | #import "UserCenter.h" 11 | 12 | @implementation SubsucribeTopicRequest 13 | -(void)loadRequest{ 14 | [super loadRequest]; 15 | self.PATH = @"/topicSubscribe"; 16 | self.METHOD = @"POST"; 17 | self.title = @""; 18 | self.httpHeaderFields = @{@"M-API-KEY":[UserCenter sharedInstance].token}; 19 | } 20 | @end 21 | -------------------------------------------------------------------------------- /rssreader/Home/Request/TagListRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // TagListRequest.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/8. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Request.h" 10 | 11 | @interface TagListRequest : Request 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Request/TagListRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // TagListRequest.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/8. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "TagListRequest.h" 10 | 11 | @implementation TagListRequest 12 | -(void)loadRequest{ 13 | [super loadRequest]; 14 | self.PATH = @"/tagList"; 15 | self.METHOD = @"GET"; 16 | } 17 | @end 18 | -------------------------------------------------------------------------------- /rssreader/Home/Request/TopicDetailRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicDetailRequest.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/15. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Request.h" 10 | 11 | @interface TopicDetailRequest : Request 12 | @property(nonatomic,strong) NSNumber *page; 13 | @property(nonatomic,strong) NSString *title; 14 | @end 15 | -------------------------------------------------------------------------------- /rssreader/Home/Request/TopicDetailRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // TopicDetailRequest.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/15. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "TopicDetailRequest.h" 10 | 11 | @implementation TopicDetailRequest 12 | -(void)loadRequest{ 13 | [super loadRequest]; 14 | self.PATH = @"/topic"; 15 | self.METHOD = @"POST"; 16 | self.page = @1; 17 | self.title = @""; 18 | } 19 | @end 20 | -------------------------------------------------------------------------------- /rssreader/Home/Request/TopicRecommendRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicRecommendRequest.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/14. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Request.h" 10 | 11 | @interface TopicRecommendRequest : Request 12 | @property(nonatomic,strong) NSNumber *pageSize; 13 | @property(nonatomic,strong) NSNumber *page; 14 | @property(nonatomic,strong) NSString *tagName; 15 | @end 16 | -------------------------------------------------------------------------------- /rssreader/Home/Request/TopicRecommendRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // TopicRecommendRequest.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/14. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "TopicRecommendRequest.h" 10 | 11 | @implementation TopicRecommendRequest 12 | -(void)loadRequest{ 13 | [super loadRequest]; 14 | self.PATH = @"/topicRecommend"; 15 | self.METHOD = @"POST"; 16 | self.pageSize = DEFAULT_PAGE_SIZE; 17 | self.page = @1; 18 | self.tagName = @"推荐"; 19 | } 20 | @end 21 | -------------------------------------------------------------------------------- /rssreader/Home/Rescource/Default-568h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuchaowe/EasyRSS/59c588577139bc289d581a47d7b7ca52d5d7b2e2/rssreader/Home/Rescource/Default-568h.png -------------------------------------------------------------------------------- /rssreader/Home/Rescource/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuchaowe/EasyRSS/59c588577139bc289d581a47d7b7ca52d5d7b2e2/rssreader/Home/Rescource/Default.png -------------------------------------------------------------------------------- /rssreader/Home/Rescource/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuchaowe/EasyRSS/59c588577139bc289d581a47d7b7ca52d5d7b2e2/rssreader/Home/Rescource/Default@2x.png -------------------------------------------------------------------------------- /rssreader/Home/Rescource/XinGothic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuchaowe/EasyRSS/59c588577139bc289d581a47d7b7ca52d5d7b2e2/rssreader/Home/Rescource/XinGothic.otf -------------------------------------------------------------------------------- /rssreader/Home/Rescource/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuchaowe/EasyRSS/59c588577139bc289d581a47d7b7ca52d5d7b2e2/rssreader/Home/Rescource/bg.jpg -------------------------------------------------------------------------------- /rssreader/Home/Rescource/html/detail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | #author# 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 |

#title#

17 |
18 | #publishDate# 19 | #author# 20 |
21 |
#content#
22 | 23 |
24 |
25 |
26 |
27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /rssreader/Home/Rescource/html/page_mp_article_improve236317.css: -------------------------------------------------------------------------------- 1 | html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;line-height:1.6}body{-webkit-touch-callout:none;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;background-color:#f3f3f3;line-height:inherit}h1,h2,h3,h4,h5,h6{font-weight:400;font-size:16px}*{margin:0;padding:0;font-style:normal}a{color:#607fa6;text-decoration:none}.rich_media_inner{font-size:15px;word-wrap:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}.rich_media_area_primary{position:relative;padding:10px 15px 15px;background-color:#fff}.rich_media_area_primary:before{content:" ";position:absolute;left:0;top:0;width:100%;height:1px;border-top:1px solid #e5e5e5;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(0.5);transform:scaleY(0.5);top:auto;bottom:-2px}.rich_media_area_extra{padding:0 15px 0}.rich_media_title{margin-bottom:12px;line-height:1.4;font-weight:400;font-size:24px}.rich_media_meta_list{overflow:hidden;margin-bottom:18px;line-height:20px}.rich_media_meta{float:left;margin-right:8px;margin-bottom:10px}.rich_media_meta_tag{position:relative;padding:0 .5em 0 1.5em;border-top-left-radius:36% 100%;-moz-border-radius-topleft:36% 100%;-webkit-border-top-left-radius:36% 100%;border-top-right-radius:36% 100%;-moz-border-radius-topright:36% 100%;-webkit-border-top-right-radius:36% 100%;border-bottom-left-radius:36% 100%;-moz-border-radius-bottomleft:36% 100%;-webkit-border-bottom-left-radius:36% 100%;border-bottom-right-radius:36% 100%;-moz-border-radius-bottomright:36% 100%;-webkit-border-bottom-right-radius:36% 100%;color:#fff;background-color:#b9b9b9}.icon_meta_copyright{width:1em;position:absolute;top:50%;margin-top:-8px;left:2px}.rich_media_meta_text{color:#8c8c8c}.rich_media_meta_nickname{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:9em}.rich_media_thumb{width:100%;margin-bottom:6px}.rich_media_content{overflow:hidden;color:#3e3e3e}.rich_media_content *{max-width:100%!important;box-sizing:border-box!important;-webkit-box-sizing:border-box!important;word-wrap:break-word!important}.rich_media_content p{clear:both;min-height:1em;white-space:pre-wrap}.rich_media_content .list-paddingleft-2{padding-left:30px}.rich_media_content blockquote{margin:0;padding-left:10px;border-left:3px solid #dbdbdb}img{height:auto!important} -------------------------------------------------------------------------------- /rssreader/Home/Rescource/html/page_mp_article_improve_combo238f07.css: -------------------------------------------------------------------------------- 1 | .selectTdClass{background-color:#edf5fa!important}table.noBorderTable td,table.noBorderTable th,table.noBorderTable caption{border:1px dashed #ddd!important}table{margin-bottom:10px;border-collapse:collapse;display:table;width:100%!important}td,th{word-wrap:break-word;word-break:break-all;padding:5px 10px;border:1px solid #DDD}caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center}th{border-top:2px solid #BBB;background:#f7f7f7}.ue-table-interlace-color-single{background-color:#fcfcfc}.ue-table-interlace-color-double{background-color:#f7faff}td p{margin:0;padding:0}.res_iframe{display:block;width:100%;background-color:transparent;border:0}.vote_area{display:block;position:relative;margin:14px 0;white-space:normal!important}.vote_iframe{width:100%;height:100%;background-color:transparent;border:0}form{display:none!important}@media screen and (min-width:0\0) and (min-resolution:72dpi){.rich_media_content table{table-layout:fixed!important}.rich_media_content td,.rich_media_content th{width:auto!important}}.rich_media_content em{font-style:italic}.rich_media_content fieldset{min-width:0}.rich_media_meta_list{overflow:visible;*zoom:1}.rich_media_meta_list:after{content:"\200B";display:block;height:0;clear:both}.tc{text-align:center}.tr{text-align:right}.tips_global{color:#8c8c8c}.rich_split_tips{margin:20px 0;min-height:24px}.rich_media_tool_tips{margin-bottom:8px}.rich_media_tool{overflow:hidden;padding-top:15px;line-height:32px}.rich_media_tool .meta_primary{float:left;margin-right:10px}.rich_media_tool .meta_extra{float:right;margin-left:10px}.rich_media_tool .meta_praise{margin-right:0;margin-left:8px}.media_tool_meta i{vertical-align:0;position:relative;top:1px;margin-right:3px}.meta_praise{-webkit-tap-highlight-color:rgba(0,0,0,0);outline:0;min-width:3.5em}.meta_praise .praise_num{display:inline-block;vertical-align:top}.icon_praise_gray{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAA+CAYAAAA1dwvuAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACd0lEQVRYhe2XMWhUMRjHfycdpDg4iJN26CQih4NUlFIc3iTasaAO+iZBnorIId2CDg6PLqWDXSy0p28TJ6ejILgoKiLFSeRcnASLnDf2HPKll8b3ah5NQPB+cHzJl0v+73J5Sf6NwWCAD6kqxoEV4BywCTwA2j59V9QlxrxUNJeBOSkfBtaAHvDcp/O+GkJHJd4H7kr5nm/nOkJHJH4FHkv5WAyhUxLfAgelvBlUKFXFBNCU6oYl+j6oEHohADwFtoDTUn8dTChVxX7gjlSfSJyS+CaYEDCPXs4d4IXkzDR+8BWqfI9SVUyil/ENST20ml8BF4Afu4z9HT3V80B/TAY9CxTABNAHxp1Oj4B1q34dWAamGa5Al0PALfSs3TS/aE1EcERWgQXgozPIN+Ai6O2ljFQVM8BLZJqN0KTEhgj9kvrViqf1wYz5BcoXQ38Pg9uckfiuSigU0xLXowmlqpgCjgNd4FM0IeCKxGcmEUtoRqLZScILpaqYA06iN9/tTTfGLzKvxLKdDCqUquIEcB59xK9GE2J4xLeBn3ZD1abaq/sQqSpmgWvo82rBbTdCPeAA4N69/noXS1XhphaBz27SPPVtapz/FXSBFsNDcgcN3wvkiBEjRoSndAtqLXXKvuvtYfMs+SP3T3tYm6ge1iaqh7UJ62HRTqNZko/mYV3CeVjA9rAuUTxsGd4edrcX1vWwddn2sHmWaA/bWuq4HnYLff3aC7U8bAiaMPyPJp3GhnxCUOlhQxPdwxrieViLbp4lUT2sIbqHNcTzsBYbeZZE9bCGeB7WIrqHNbTzLNnhYWMIlXpYI9Rz8gM8/GsFi3mW/Ace9jf8QZwIX5o4uQAAAABJRU5ErkJggg==) no-repeat 0 0;width:13px;height:13px;vertical-align:middle;display:inline-block;-webkit-background-size:100% auto;background-size:100% auto}.icon_praise_gray.praised{background-position:0 -18px}.praised .icon_praise_gray{background-position:0 -18px}.rich_tips{margin-top:25px;margin-bottom:0;min-height:24px;text-align:center}.rich_tips .tips{display:inline-block;vertical-align:middle}.rich_tips .tips,.rich_tips .rich_icon{vertical-align:middle}.rich_tips .rich_icon{margin-top:-3px 5px 0 0}.rich_tips.with_line{border-top:1px dotted #e1e1e1}.rich_tips.with_line .tips{position:relative;top:-12px;padding-left:16px;padding-right:16px;background-color:#f3f3f3}.rich_tips.with_line{line-height:16px}.rich_tips.with_line .tips{top:-11px;padding-left:.35em;padding-right:.35em}.title_tips .tips{color:#868686;font-size:16px}.loading_tips{margin:36px 0 20px}.title_bottom_tips{margin-top:-10px}.icon_arrow_gray{width:7px}.icon_loading_white{width:16px}.icon_loading_white.icon_before{margin-right:1em}.icon_loading_white.icon_after{margin-left:1em}.btn{display:block;padding-left:14px;padding-right:14px;font-size:18px;text-align:center;text-decoration:none;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;color:#fff;line-height:42px;-webkit-tap-highlight-color:rgba(255,255,255,0)}.btn.btn_inline{display:inline-block}.btn_primary{background-color:#04be02}.btn_primary:not(.btn_disabled):visited{color:#fff}.btn_primary:not(.btn_disabled):active{color:rgba(255,255,255,0.4);background-color:#039702}.btn_disabled{color:rgba(255,255,255,0.6)}.wx_poptips{position:fixed;z-index:3;width:120px;min-height:120px;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);background:rgba(40,40,40,0.5)!important;filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#80282828',endcolorstr = '#80282828');text-align:center;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;color:#fff}.wx_poptips .icon_toast{width:53px;margin:15px 0 0}.wx_poptips .toast_content{margin:0 0 15px}.discuss_container .rich_media_title{font-size:18px}.discuss_container .discuss_message{word-wrap:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}.discuss_container.disabled .btn_discuss{color:#60f05f}.discuss_container.access .discuss_container_inner{padding:15px 15px 0}.discuss_container.editing .discuss_container_inner{padding-bottom:25px}.discuss_container.editing .frm_textarea_box{margin:0 -15px}.discuss_container.editing .frm_textarea{height:78px}.discuss_container.editing .frm_append.counter{display:block}.discuss_container.editing .discuss_btn_wrp{display:block}.discuss_container.editing .discuss_icon_tips{margin-top:0;margin-bottom:-14px}.discuss_container.warning .counter{color:#e15f63}.frm_textarea{width:100%;background-color:transparent;border:0;display:block;font-size:14px;-webkit-box-sizing:border-box;box-sizing:border-box;height:37px;padding:10px 15px;resize:none;outline:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}.frm_textarea_box_wrp{position:relative}.frm_textarea_box_wrp:before{content:" ";position:absolute;left:0;top:0;width:100%;height:1px;border-top:1px solid #e7e6e4;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(0.5);transform:scaleY(0.5);top:-1px}.frm_textarea_box_wrp:after{content:" ";position:absolute;left:0;top:0;width:100%;height:1px;border-top:1px solid #e7e6e4;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(0.5);transform:scaleY(0.5);top:auto;bottom:-2px}.frm_textarea_box{display:block;background-color:#fff}.frm_append.counter{display:none;position:absolute;right:8px;bottom:8px;color:#a3a3a3;font-weight:400;font-style:normal;font-size:12px}.frm_append .current_num.warn{color:#f43631}.discuss_btn_wrp{display:none;margin-top:20px;margin-bottom:20px;text-align:right}.btn_discuss{padding-left:1.5em;padding-right:1.5em}.discuss_list{margin-top:-5px;padding-bottom:20px;font-size:15px}.discuss_item{position:relative;padding-left:45px;margin-top:26px;*zoom:1}.discuss_item:after{content:"\200B";display:block;height:0;clear:both}.discuss_item .user_info{min-height:20px;overflow:hidden}.discuss_item .nickname{display:block;font-weight:400;font-style:normal;color:#727272;width:9em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal}.discuss_item .avatar{position:absolute;top:0;left:0;top:3px;width:35px;height:35px;background-color:#ccc;vertical-align:top;margin-top:0;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.discuss_item .discuss_message{color:#3e3e3e;line-height:1.5}.discuss_item .discuss_time{color:#8c8c8c;font-size:12px}.discuss_item .discuss_status{color:#ff7a21;white-space:nowrap}.discuss_item .discuss_status i{font-style:normal;margin-right:2px}.discuss_item .discuss_opr{float:right}.discuss_item .discuss_opr .meta_praise{display:inline-block;text-align:right;padding-top:5px;margin-top:-5px}.discuss_icon_tips{margin-bottom:20px}.discuss_icon_tips img{vertical-align:middle;margin-left:3px;margin-top:-4px}.discuss_icon_tips .icon_edit{width:12px}.discuss_icon_tips .icon_access{width:13px}.rich_media_extra{font-size:15px;position:relative}.rich_media_extra .extra_link{display:block}.rich_media_extra img{vertical-align:middle;margin-top:-3px}.rich_media_extra .appmsg_banner{width:100%}.rich_media_extra .ad_msg_mask{position:absolute;left:0;top:0;width:100%;height:100%;text-align:center;line-height:200px;background-color:#000;filter:alpha(opacity = 20);-moz-opacity:.2;-khtml-opacity:.2;opacity:.2}.mpda_bottom_container .rich_media_extra{padding-bottom:15px}.btn_default.btn_line,.btn_primary.btn_line{background-color:#fff;color:#04be02;border:1px solid #04be02;font-size:15px}.promotion_tag{position:absolute;display:block;height:23px;line-height:23px;width:85px;background:transparent url(../images/promotion_tag_bg2318b8.png) no-repeat 0 0;-webkit-background-size:85px 23px;background-size:85px 23px;font-size:15px;font-style:normal;color:#eaeaea;padding-left:10px;left:0;bottom:10px}.top_banner{background-color:#fff}.top_banner .rich_media_extra{padding:15px 15px 20px 15px}.top_banner .rich_media_extra .extra_link{position:relative;padding-bottom:10px}.top_banner .rich_media_extra .extra_link:before{content:" ";position:absolute;left:0;top:0;width:100%;height:1px;border-top:1px solid #d6d6d6;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(0.5);transform:scaleY(0.5);top:auto;bottom:-2px}.top_banner .rich_media_extra .extra_link:active,.top_banner .rich_media_extra .extra_link:focus{outline:0;border:0}.top_banner .rich_media_extra .appmsg_banner{width:100%;vertical-align:top;outline:0}.top_banner .rich_media_extra .appmsg_banner:active,.top_banner .rich_media_extra .appmsg_banner:focus{outline:0;border:0}.top_banner .rich_media_extra .promotion_tag{height:20px;line-height:20px;width:72px;background:transparent url(../images/promotion_tag_bg_small2318b8.png) no-repeat 0 0;font-size:12px;-webkit-background-size:72px 20px;background-size:72px 20px}.top_banner .rich_media_extra .ad_msg_mask{position:absolute;left:0;top:0;width:100%;height:100%;text-align:center;line-height:200px;background-color:#000;filter:alpha(opacity = 20);-moz-opacity:.2;-khtml-opacity:.2;opacity:.2}.top_banner .rich_media_extra .ad_msg_mask img{position:absolute;width:16px;top:50%;margin-top:-8px;left:50%;margin-left:-8px}.wrp_preview_group{padding-top:100px}.preview_group{position:relative;min-height:83px;background-color:#fff;border:1px solid #e7e7eb;-webkit-text-size-adjust:none;text-size-adjust:none}.preview_group.fixed_pos{position:fixed;bottom:0;left:0;right:0}.preview_group .preview_group_inner{padding:14px}.preview_group .preview_group_inner .preview_group_info{padding-left:68px;color:#8d8d8d;font-size:14px}.preview_group .preview_group_inner .preview_group_info .preview_group_title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal;color:#000;font-weight:400;font-style:normal;padding-right:73px;max-width:142px;display:block}.preview_group .preview_group_inner .preview_group_info .preview_group_desc{padding-right:65px;display:inline-block;line-height:20px}.preview_group .preview_group_inner .preview_group_info .preview_group_avatar{position:absolute;width:55px;height:55px;left:13px;top:50%;margin-top:-27px;z-index:1}.preview_group .preview_group_inner .preview_group_info .preview_group_avatar.br_radius{border-radius:100%;-moz-border-radius:100%;-webkit-border-radius:100%}.preview_group .preview_group_inner .preview_group_opr{position:absolute;line-height:83px;top:0;right:13px}.preview_group .preview_group_inner .preview_group_opr .btn{padding:0;min-width:60px;min-height:30px;height:auto;line-height:30px;text-align:center}.preview_group.preview_card .card_inner .preview_card_avatar{position:absolute;width:57px;height:57px;left:13px;top:50%;margin-top:-28px}.preview_group.preview_card .card_inner .preview_group_info{padding-left:70px}.preview_group.preview_card .card_inner .preview_group_info .preview_group_title2{width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal;padding-right:0;display:block}.preview_group.preview_card .card_inner .preview_group_info .preview_group_desc{padding-right:0}.preview_group.preview_card .card_inner .preview_group_info.append_btn .preview_group_desc,.preview_group.preview_card .card_inner .preview_group_info.append_btn .preview_group_title{padding-right:68px;width:auto}.preview_group.obvious_app{width:100%}.preview_group.obvious_app .preview_group_inner{padding:0}.preview_group.obvious_app .pic_app{width:58.3%;height:100%;display:inline-block;margin-right:2%;vertical-align:top}.preview_group.obvious_app .pic_app img{width:100%;vertical-align:top;margin-top:0}.preview_group.obvious_app .info_app{display:inline-block;width:38%;color:#8a8a8a;font-size:12px;box-sizing:border-box;-webkit-box-sizing:border-box;position:absolute;left:62%;top:0;height:100%}.preview_group.obvious_app .info_app .name_app{color:#000;font-size:16px;width:95%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal;margin-top:4%}.preview_group.obvious_app .info_app .profile_app{line-height:12px}.preview_group.obvious_app .info_app .profile_app span{line-height:16px}.preview_group.obvious_app .info_app .profile_app em{font-size:9px;line-height:16px;margin:0 5px;font-weight:400;font-style:normal;color:#dfdfdf}.preview_group.obvious_app .info_app .dm_app{line-height:20px;vertical-align:middle;position:absolute;left:0;bottom:5%}.preview_group.obvious_app .info_app .dm_app p{line-height:12px}.preview_group.obvious_app .info_app .dm_app .ad_btn{display:block;color:#04be02;font-size:15px;padding-left:22px}.preview_group.obvious_app .info_app .dm_app .ad_btn.btn_download{background:transparent url(../images/icon58_download@3x.png) no-repeat 0 0;-webkit-background-size:19px 19px;background-size:19px 19px}.preview_group.obvious_app .info_app .dm_app .ad_btn.btn_install{background:transparent url(../images/icon58_install@3x.png) no-repeat 0 0;-webkit-background-size:19px 19px;background-size:19px 19px}.preview_group.obvious_app .info_app .dm_app .ad_btn.btn_installed{background:transparent url(../images/icon58_installed@3x.png) no-repeat 0 0;-webkit-background-size:19px 19px;background-size:19px 19px;color:#8a8a8a}.preview_group.obvious_app .info_app .dm_app .ad_btn.btn_open{background:transparent url(../images/icon58_open@3x.png) no-repeat 0 0;-webkit-background-size:19px 19px;background-size:19px 19px}.preview_group.obvious_app .info_app .dm_app .extra_info{font-size:9px}.reward_area{padding:26px 0 12px}.reward_access{display:inline-block;padding:0 1.8em;line-height:2.2;border:1px solid #d65645;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;color:#d65645;-webkit-tap-highlight-color:rgba(0,0,0,0)}.reward_access:active{background-color:#d65645;color:#fff}.reward_tips{margin-bottom:5px}@media screen and (max-width:1023px){.qr_code_pc_outer{display:none!important}}@media screen and (min-width:1024px){.rich_media{width:740px;margin-left:auto;margin-right:auto}.rich_media_inner{padding:20px}.rich_media_meta{max-width:none}.rich_media_content{min-height:350px}.rich_media_title{padding-bottom:10px;margin-bottom:14px;border-bottom:1px solid #e7e7eb}body{background-color:#fff}.discuss_container.access{width:740px;margin-left:auto;margin-right:auto;background-color:#fff}.discuss_container.editing .frm_textarea_box{margin:0}.frm_textarea_box{position:relative}.frm_textarea_box:before{content:" ";position:absolute;left:0;top:0;width:1px;height:100%;border-left:1px solid #e7e6e4;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleX(0.5);transform:scaleX(0.5)}.frm_textarea_box:after{content:" ";position:absolute;left:0;top:0;width:1px;height:100%;border-left:1px solid #e7e6e4;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleX(0.5);transform:scaleX(0.5);left:auto;right:-2px}.rich_media_meta.nickname{max-width:none}.rich_tips.with_line .tips{background-color:#fff}}@media screen and (min-width:1025px){.rich_media_inner{border:1px solid #d9dadc;border-top-width:0}body{background-color:#e7e8eb;font-family:"Helvetica Neue",Helvetica,"Hiragino Sans GB","Microsoft YaHei","΢ÈíÑźÚ",Arial,sans-serif}.rich_media{position:relative}.rich_media_inner{background-color:#fff;padding-bottom:100px}.rich_media_inner{position:relative}.qr_code_pc_outer{display:block!important;position:fixed;left:0;right:0;top:20px;color:#717375;text-align:center}.qr_code_pc_inner{position:relative;width:740px;margin-left:auto;margin-right:auto}.qr_code_pc{position:absolute;right:-145px;top:0;padding:16px;border:1px solid #d9dadc;background-color:#fff}.qr_code_pc p{font-size:14px;line-height:20px}.qr_code_pc_img{width:102px;height:102px}} -------------------------------------------------------------------------------- /rssreader/Home/Rescource/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuchaowe/EasyRSS/59c588577139bc289d581a47d7b7ca52d5d7b2e2/rssreader/Home/Rescource/icon.png -------------------------------------------------------------------------------- /rssreader/Home/Rescource/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuchaowe/EasyRSS/59c588577139bc289d581a47d7b7ca52d5d7b2e2/rssreader/Home/Rescource/icon@2x.png -------------------------------------------------------------------------------- /rssreader/Home/Rescource/rssIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhuchaowe/EasyRSS/59c588577139bc289d581a47d7b7ca52d5d7b2e2/rssreader/Home/Rescource/rssIcon@2x.png -------------------------------------------------------------------------------- /rssreader/Home/Scene/Base/BaseScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseScene.h 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-22. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Scene.h" 10 | 11 | @interface BaseScene : Scene 12 | @end 13 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Base/BaseScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseScene.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-22. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "BaseScene.h" 10 | 11 | @interface BaseScene () 12 | 13 | @end 14 | 15 | @implementation BaseScene 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/ChannelScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // ChannelScene.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/9. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Scene.h" 10 | 11 | @interface ChannelScene : Scene 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/ChannelScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // ChannelScene.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/9. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "ChannelScene.h" 10 | #import 11 | #import "ChannelSceneModel.h" 12 | #import "RssListScene.h" 13 | #import "FeedCell.h" 14 | #import "AddScene.h" 15 | #import "RDNavigationController.h" 16 | #import "ChannelTableView.h" 17 | #import "ActionSceneModel.h" 18 | 19 | 20 | @interface ChannelScene () 21 | 22 | @property (nonatomic, strong) HTHorizontalSelectionList *selectionList; 23 | @property (nonatomic, strong) NSMutableArray *tagList; 24 | @property (nonatomic, strong) SceneScrollView *scrollView; 25 | @end 26 | 27 | @implementation ChannelScene 28 | 29 | - (void)viewDidLoad { 30 | [super viewDidLoad]; 31 | self.title = @"频道"; 32 | 33 | 34 | UIButton *rssbutton = [IconFont buttonWithIcon:[IconFont icon:@"fa_rss" fromFont:fontAwesome] fontName:fontAwesome size:24.0f color:[UIColor whiteColor]]; 35 | [self showBarButton:NAV_RIGHT button:rssbutton]; 36 | 37 | 38 | self.selectionList = [[HTHorizontalSelectionList alloc] init]; 39 | self.selectionList.delegate = self; 40 | self.selectionList.dataSource = self; 41 | [self.selectionList setTitleColor:[UIColor flatDarkOrangeColor] forState:UIControlStateSelected]; 42 | self.selectionList.selectionIndicatorColor = [UIColor flatDarkOrangeColor]; 43 | self.selectionList.bottomTrimColor = [UIColor flatDarkOrangeColor]; 44 | [self.view addSubview:self.selectionList]; 45 | [self.selectionList alignTop:@"0" leading:@"0" bottom:nil trailing:@"0" toView:self.selectionList.superview]; 46 | [self.selectionList constrainHeight:@"40"]; 47 | 48 | 49 | self.scrollView = [[SceneScrollView alloc]init]; 50 | self.scrollView.backgroundColor = [UIColor whiteColor]; 51 | self.scrollView.delegate = self; 52 | self.scrollView.pagingEnabled = YES; 53 | self.scrollView.showsHorizontalScrollIndicator = NO; 54 | self.scrollView.showsVerticalScrollIndicator = NO; 55 | self.scrollView.bounces = NO; 56 | [self.view addSubview:self.scrollView]; 57 | [self.scrollView addHorizontalContentView]; 58 | [self.scrollView horizontalConstrainTopSpaceToView:self.selectionList predicate:@"0"]; 59 | [self.scrollView horizontalAlignBottomWithView:self.scrollView.superview predicate:@"0"]; 60 | [self.scrollView alignLeading:@"0" trailing:@"0" toView:self.scrollView.superview]; 61 | 62 | @weakify(self); 63 | TagListRequest *req = [TagListRequest Request]; 64 | [[ActionSceneModel sharedInstance] sendRequest:req success:^{ 65 | @strongify(self); 66 | self.tagList = [req.output objectAtPath:@"Data/list"]; 67 | NSUInteger count = self.tagList.count; 68 | if(count>0){ 69 | [self.selectionList reloadData]; 70 | [self.tagList enumerateObjectsUsingBlock:^(NSString *title, NSUInteger idx, BOOL *stop) { 71 | ChannelTableView *sqTableView = [[ChannelTableView alloc]init]; 72 | sqTableView.pushBlock = ^(UIViewController *controller){ 73 | [self.navigationController pushViewController:controller animated:YES]; 74 | }; 75 | [self.scrollView addHorizontalSubView:sqTableView atIndex:idx]; 76 | if(idx == count-1){ 77 | [self.scrollView endWithHorizontalView:sqTableView]; 78 | } 79 | [sqTableView addPullRefreshWithTagName:title]; 80 | }]; 81 | } 82 | } error:nil]; 83 | 84 | } 85 | 86 | -(void)rightButtonTouch{ 87 | RDNavigationController *nav = [[RDNavigationController alloc]initWithRootViewController:[[AddScene alloc]init]]; 88 | [self presentViewController:nav animated:YES completion:nil]; 89 | } 90 | 91 | 92 | #pragma mark - HTHorizontalSelectionListDataSource Protocol Methods 93 | 94 | - (NSInteger)numberOfItemsInSelectionList:(HTHorizontalSelectionList *)selectionList { 95 | return self.tagList.count; 96 | } 97 | 98 | - (NSString *)selectionList:(HTHorizontalSelectionList *)selectionList titleForItemWithIndex:(NSInteger)index { 99 | return self.tagList[index]; 100 | } 101 | 102 | #pragma mark - HTHorizontalSelectionListDelegate Protocol Methods 103 | - (void)selectionList:(HTHorizontalSelectionList *)selectionList didSelectButtonWithIndex:(NSInteger)index { 104 | [self.scrollView scrollRectToVisible:CGRectMake(self.scrollView.width * index, 0, self.scrollView.width, self.scrollView.height) animated:YES]; 105 | } 106 | 107 | 108 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 109 | CGFloat pageWidth = scrollView.frame.size.width; 110 | NSInteger index = scrollView.contentOffset.x / pageWidth; 111 | [self.selectionList setSelectedButtonIndex:index animated:YES]; 112 | } 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/ChannelTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ChannelTableView.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/3/3. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SceneTableView.h" 10 | typedef void (^PushBlock)(UIViewController *controller); 11 | @interface ChannelTableView : SceneTableView 12 | @property(nonatomic,copy)PushBlock pushBlock; 13 | -(void)addPullRefreshWithTagName:(NSString *)tagName; 14 | @end 15 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/ChannelTableView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ChannelTableView.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/3/3. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "ChannelTableView.h" 10 | #import "ChannelSceneModel.h" 11 | #import "FeedCell.h" 12 | #import "SquareHeader.h" 13 | #import "SquareFooter.h" 14 | #import "UIColor+RSS.h" 15 | 16 | @interface ChannelTableView() 17 | @property (strong, nonatomic) SceneTableView *tableView; 18 | @property(nonatomic,retain)ChannelSceneModel *channelSceneModel; 19 | @end 20 | 21 | @implementation ChannelTableView 22 | 23 | -(instancetype)init{ 24 | self = [super init]; 25 | if(self){ 26 | self.separatorStyle = UITableViewCellSeparatorStyleNone; 27 | self.delegate = self; 28 | self.dataSource = self; 29 | self.rowHeight = 84.0f; 30 | 31 | _channelSceneModel = [ChannelSceneModel SceneModel]; 32 | @weakify(self); 33 | [self registerClass:[FeedCell class] forCellReuseIdentifier:@"FeedCell"]; 34 | 35 | [[RACObserve(self.channelSceneModel, feedList) 36 | filter:^BOOL(FeedList* value) { 37 | return value !=nil; 38 | }] 39 | subscribeNext:^(FeedList *value) { 40 | @strongify(self); 41 | self.channelSceneModel.dataArray = [value.pagination 42 | success:self.channelSceneModel.dataArray 43 | newArray:value.list]; 44 | self.channelSceneModel.request.page = value.pagination.page; 45 | [self reloadData]; 46 | [self endAllRefreshingWithIntEnd:value.pagination.isEnd.integerValue]; 47 | }]; 48 | 49 | [[RACObserve(self.channelSceneModel.request, state) 50 | filter:^BOOL(NSNumber *state) { 51 | @strongify(self); 52 | return self.channelSceneModel.request.failed; 53 | }] 54 | subscribeNext:^(id x) { 55 | @strongify(self); 56 | self.channelSceneModel.request.page = self.channelSceneModel.feedList.pagination.page?:@1; 57 | [self endAllRefreshingWithIntEnd:self.channelSceneModel.feedList.pagination.isEnd.integerValue]; 58 | }]; 59 | 60 | } 61 | return self; 62 | } 63 | 64 | -(void)addPullRefreshWithTagName:(NSString *)tagName{ 65 | 66 | self.channelSceneModel.request.tagName = tagName; 67 | @weakify(self); 68 | [self addPullToRefreshWithActionHandler:^{ 69 | @strongify(self); 70 | self.channelSceneModel.request.page = @1; 71 | self.channelSceneModel.request.requestNeedActive = YES; 72 | } customer:YES]; 73 | [self.pullToRefreshView setCustomView: [[SquareHeader alloc]initWithScrollView:self]]; 74 | 75 | [self addInfiniteScrollingWithActionHandler:^{ 76 | @strongify(self); 77 | self.channelSceneModel.request.page = [self.channelSceneModel.request.page increase:@1]; 78 | self.channelSceneModel.request.requestNeedActive = YES; 79 | } customer:YES]; 80 | [self.infiniteScrollingView setCustomView:[[SquareFooter alloc] initWithScrollView:self]]; 81 | [self triggerPullToRefresh]; 82 | } 83 | 84 | 85 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 86 | return self.channelSceneModel.dataArray.count; 87 | } 88 | 89 | - (FeedCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 90 | FeedCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FeedCell" forIndexPath:indexPath]; 91 | cell.backGroundView.backgroundColor = [UIColor colorAtIndex:indexPath.row]; 92 | FeedEntity *feed = [self.channelSceneModel.dataArray objectAtIndex:indexPath.row]; 93 | [cell reload:feed]; 94 | [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; 95 | [cell setAccessoryType:UITableViewCellAccessoryNone]; 96 | return cell; 97 | } 98 | 99 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 100 | FeedEntity *entity = [self.channelSceneModel.dataArray objectAtIndex:indexPath.row]; 101 | [URLManager pushURLString:entity.openUrl animated:YES]; 102 | } 103 | @end 104 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/EzUILabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // EzUILabel.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 14/12/22. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EzUILabel : UILabel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/EzUILabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // EzUILabel.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 14/12/22. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "EzUILabel.h" 10 | 11 | @implementation EzUILabel 12 | 13 | /* 14 | // Only override drawRect: if you perform custom drawing. 15 | // An empty implementation adversely affects performance during animation. 16 | - (void)drawRect:(CGRect)rect { 17 | // Drawing code 18 | } 19 | */ 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/AddScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // AddScene.h 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-18. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "FavScene.h" 10 | 11 | @interface AddScene : Scene 12 | @property (strong, nonatomic) UITextField *textView; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/AddScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // AddScene.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-18. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "AddScene.h" 10 | #import "FeedSceneModel.h" 11 | #import "RssListScene.h" 12 | #import "WeChatListScene.h" 13 | #import "ActionSceneModel.h" 14 | #import "AddFeedRequest.h" 15 | @interface AddScene () 16 | @property (strong, nonatomic) SceneScrollView *scrollerView; 17 | @property (nonatomic,strong) UISegmentedControl *segmented; 18 | @end 19 | 20 | @implementation AddScene 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | 25 | _segmented = [[UISegmentedControl alloc]initWithItems:@[@"RSS",@"微信",@"话题"]]; 26 | [_segmented setFrame:CGRectMake(0, 0, 200, 32)]; 27 | [_segmented setTintColor:[UIColor whiteColor]]; 28 | _segmented.selectedSegmentIndex = 0; 29 | [self setTitleView:_segmented]; 30 | 31 | self.scrollerView = [[SceneScrollView alloc]init]; 32 | self.scrollerView.backgroundColor = [UIColor whiteColor]; 33 | [self addSubView:self.scrollerView extend:EXTEND_TOP]; 34 | [self.scrollerView addContentView]; 35 | 36 | _textView = [[UITextField alloc]init]; 37 | _textView.delegate = self; 38 | _textView.clearButtonMode = UITextFieldViewModeWhileEditing; 39 | _textView.returnKeyType = UIReturnKeyGo; 40 | [self.scrollerView.contentView addSubview:_textView]; 41 | 42 | [_textView alignTop:@"20" leading:@"20" bottom:nil trailing:@"20" toView:_textView.superview]; 43 | [_textView constrainHeight:@"30"]; 44 | [self.scrollerView endWithView:_textView]; 45 | 46 | UIButton *leftbutton = [IconFont buttonWithIcon:[IconFont icon:@"fa_chevron_left" fromFont:fontAwesome] fontName:fontAwesome size:24.0f color:[UIColor whiteColor]]; 47 | [self showBarButton:NAV_LEFT button:leftbutton]; 48 | 49 | UIButton *rightbutton = [IconFont buttonWithIcon:[IconFont icon:@"fa_check" fromFont:fontAwesome] fontName:fontAwesome size:24.0f color:[UIColor whiteColor]]; 50 | [self showBarButton:NAV_RIGHT button:rightbutton]; 51 | 52 | [_textView becomeFirstResponder]; 53 | [self loadHudInKeyWindow]; 54 | 55 | @weakify(self); 56 | 57 | [RACObserve(self.segmented, selectedSegmentIndex) 58 | subscribeNext:^(NSNumber *index) { 59 | @strongify(self); 60 | if(index.integerValue == 0){ 61 | self.textView.placeholder = @"请输入RSS源地址"; 62 | }else if(index.integerValue == 1){ 63 | self.textView.placeholder = @"查询微信公众账号"; 64 | }else{ 65 | self.textView.placeholder = @"搜索相关话题"; 66 | } 67 | }]; 68 | 69 | // Do any additional setup after loading the view. 70 | } 71 | 72 | - (void)didReceiveMemoryWarning { 73 | [super didReceiveMemoryWarning]; 74 | // Dispose of any resources that can be recreated. 75 | } 76 | 77 | -(void)leftButtonTouch{ 78 | [_textView resignFirstResponder]; 79 | [self dismissViewControllerAnimated:YES completion:nil]; 80 | } 81 | 82 | /** 83 | * 导航条右按钮点击事件 84 | */ 85 | -(void)rightButtonTouch{ 86 | if(self.segmented.selectedSegmentIndex == 0){ 87 | if([NSURL URLWithString:_textView.text].scheme == nil){ 88 | _textView.text = [NSString stringWithFormat:@"http://%@",_textView.text]; 89 | } 90 | if([NSURL URLWithString:_textView.text].host != nil){ 91 | AddFeedRequest *req = [AddFeedRequest Request]; 92 | req.feedUrl = _textView.text; 93 | [self showHudIndeterminate:@"加载中..."]; 94 | [[ActionSceneModel sharedInstance] sendRequest:req success:^{ 95 | [self hideHud]; 96 | FeedEntity *feed = [[FeedEntity alloc]initWithDictionary:[req.output objectAtPath:@"Data/feed"] error:nil]; 97 | [URLManager pushURLString:feed.openUrl animated:YES]; 98 | } error:^{ 99 | [self hideHudFailed:req.message]; 100 | }]; 101 | } 102 | }else if(self.segmented.selectedSegmentIndex == 1){ 103 | WeChatListScene *scene = [[WeChatListScene alloc]init]; 104 | scene.title = self.textView.text; 105 | [self.navigationController pushViewController:scene animated:YES]; 106 | }else{ 107 | NSString *string = [NSString stringWithFormat:@"easyrss://topic?title=%@",self.textView.text.urlencode]; 108 | [URLManager pushURLString:string animated:YES]; 109 | } 110 | } 111 | 112 | - (BOOL)textFieldShouldReturn:(UITextField *)textField{ 113 | [self rightButtonTouch]; 114 | return YES; 115 | } 116 | 117 | 118 | @end 119 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/FavScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-12. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "BaseScene.h" 10 | 11 | @interface FavScene : BaseScene 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/FavScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-12. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "FavScene.h" 10 | #import "FeedSceneModel.h" 11 | #import "AddScene.h" 12 | #import "RssListScene.h" 13 | #import "FeedCell.h" 14 | #import "DiscoverySceneModel.h" 15 | #import "DataCenter.h" 16 | #import "RDNavigationController.h" 17 | #import "UserCenter.h" 18 | #import "ActionSceneModel.h" 19 | #import "DeleteSubscribeRequest.h" 20 | #import "UIColor+RSS.h" 21 | 22 | @interface FavScene () 23 | @property (strong, nonatomic) SceneTableView *tableView; 24 | @property(nonatomic,retain)FeedSceneModel *feedSceneModel; 25 | 26 | @end 27 | 28 | @implementation FavScene 29 | 30 | - (void)viewDidLoad { 31 | [super viewDidLoad]; 32 | self.title = @"订阅频道"; 33 | 34 | UIButton *rssbutton = [IconFont buttonWithIcon:[IconFont icon:@"fa_rss" fromFont:fontAwesome] fontName:fontAwesome size:24.0f color:[UIColor whiteColor]]; 35 | [self showBarButton:NAV_RIGHT button:rssbutton]; 36 | 37 | 38 | _feedSceneModel = [FeedSceneModel SceneModel]; 39 | 40 | // if([DataCenter sharedInstance].time.isNotEmpty){ 41 | // PresentRssList *presentRssListScene = [self.storyboard instantiateViewControllerWithIdentifier:@"PresentRssList"]; 42 | // CenterNav *centerNav = [[CenterNav alloc]initWithRootViewController:presentRssListScene]; 43 | // [self presentViewController:centerNav animated:NO completion:nil]; 44 | // } 45 | 46 | 47 | // if ([[UIApplication sharedApplication] backgroundRefreshStatus] != UIBackgroundRefreshStatusAvailable) { 48 | // [RMUniversalAlert showAlertInViewController:self withTitle:@"后台应用刷新" message:@"您没有开启后台刷新,请在 设置->通用->应用程序后台刷新 中开启。" cancelButtonTitle:@"确定" destructiveButtonTitle:nil otherButtonTitles:nil tapBlock:nil]; 49 | // } 50 | 51 | self.tableView = [[SceneTableView alloc]init]; 52 | 53 | self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 54 | self.tableView.delegate = self; 55 | self.tableView.dataSource = self; 56 | [self.view addSubview:self.tableView]; 57 | [self.tableView registerClass:[FeedCell class] forCellReuseIdentifier:@"FeedCell"]; 58 | 59 | [self.tableView alignToView:self.view]; 60 | 61 | @weakify(self); 62 | 63 | [self.tableView addPullToRefreshWithActionHandler:^{ 64 | @strongify(self); 65 | self.feedSceneModel.request.page = @1; 66 | self.feedSceneModel.request.requestNeedActive = YES; 67 | }]; 68 | 69 | [self.tableView addInfiniteScrollingWithActionHandler:^{ 70 | @strongify(self); 71 | self.feedSceneModel.request.page = [self.feedSceneModel.request.page increase:@1]; 72 | self.feedSceneModel.request.requestNeedActive = YES; 73 | }]; 74 | 75 | [[RACObserve(self.feedSceneModel, feedList) 76 | filter:^BOOL(FeedList* value) { 77 | return value !=nil; 78 | }] 79 | subscribeNext:^(FeedList *value) { 80 | @strongify(self); 81 | self.feedSceneModel.dataArray = [value.pagination 82 | success:self.feedSceneModel.dataArray 83 | newArray:value.list]; 84 | self.feedSceneModel.request.page = value.pagination.page; 85 | [self.tableView reloadData]; 86 | [self.tableView endAllRefreshingWithIntEnd:value.pagination.isEnd.integerValue]; 87 | }]; 88 | 89 | [[RACObserve(self.feedSceneModel.request, state) 90 | filter:^BOOL(NSNumber *state) { 91 | @strongify(self); 92 | return self.feedSceneModel.request.failed; 93 | }] 94 | subscribeNext:^(id x) { 95 | @strongify(self); 96 | self.feedSceneModel.request.page = self.feedSceneModel.feedList.pagination.page?:@1; 97 | [self.tableView endAllRefreshingWithIntEnd:self.feedSceneModel.feedList.pagination.isEnd.integerValue]; 98 | }]; 99 | 100 | [self.tableView triggerPullToRefresh]; 101 | [self loadHud:self.view]; 102 | 103 | } 104 | 105 | -(void)rightButtonTouch{ 106 | RDNavigationController *nav = [[RDNavigationController alloc]initWithRootViewController:[[AddScene alloc]init]]; 107 | [self presentViewController:nav animated:YES completion:nil]; 108 | } 109 | 110 | 111 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 112 | return 84; 113 | } 114 | 115 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 116 | return self.feedSceneModel.dataArray.count; 117 | } 118 | 119 | - (FeedCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 120 | FeedCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FeedCell" forIndexPath:indexPath]; 121 | cell.backGroundView.backgroundColor = [UIColor colorAtIndex:indexPath.row]; 122 | FeedEntity *feed = [self.feedSceneModel.dataArray objectAtIndex:indexPath.row]; 123 | [cell reload:feed]; 124 | [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; 125 | [cell setAccessoryType:UITableViewCellAccessoryNone]; 126 | return cell; 127 | } 128 | 129 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 130 | FeedEntity *feed = [self.feedSceneModel.dataArray objectAtIndex:indexPath.row]; 131 | [URLManager pushURLString:feed.openUrl animated:YES]; 132 | } 133 | 134 | - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{ 135 | return UITableViewCellEditingStyleDelete; 136 | } 137 | 138 | - (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{ 139 | return @"取消订阅"; 140 | } 141 | 142 | -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ 143 | if (editingStyle == UITableViewCellEditingStyleDelete) 144 | { 145 | FeedEntity *feed =[self.feedSceneModel.dataArray objectAtIndex:indexPath.row]; 146 | DeleteSubscribeRequest *req = [DeleteSubscribeRequest Request]; 147 | req.feedId = feed.feedId; 148 | [self showHudIndeterminate:@"正在取消"]; 149 | [[ActionSceneModel sharedInstance] sendRequest:req success:^{ 150 | [self hideHud]; 151 | [self.feedSceneModel.dataArray removeObjectAtIndex:indexPath.row]; 152 | [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationFade]; 153 | } error:^{ 154 | [self hideHudFailed:@"取消订阅失败"]; 155 | }]; 156 | } 157 | } 158 | 159 | @end 160 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/FeedCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // FeedCell.h 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-24. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FeedEntity.h" 11 | #import "SWTableViewCell.h" 12 | @interface FeedCell : EzTableViewCell 13 | @property(nonatomic,retain)UIView *backGroundView; 14 | -(void)reload:(FeedEntity *)feed; 15 | @end 16 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/FeedCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // FeedCell.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-24. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "FeedCell.h" 10 | @interface FeedCell() 11 | @property(nonatomic,retain)UIImageView *logoImageView; 12 | @property(nonatomic,retain)UILabel *titleLabel; 13 | @property(nonatomic,retain)UILabel *summaryLabel; 14 | @property(nonatomic,retain)NSMutableArray *centerConsArray; 15 | @end 16 | @implementation FeedCell 17 | 18 | -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ 19 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 20 | if(self){ 21 | _backGroundView = [[UIView alloc]init]; 22 | _backGroundView.layer.cornerRadius = 5; 23 | [self.contentView addSubview:_backGroundView]; 24 | 25 | _logoImageView = [[UIImageView alloc]init]; 26 | _logoImageView.contentMode = UIViewContentModeScaleAspectFit; 27 | _logoImageView.layer.masksToBounds = YES; 28 | _logoImageView.layer.cornerRadius = 5; 29 | [_backGroundView addSubview:_logoImageView]; 30 | 31 | _titleLabel = [[UILabel alloc]init]; 32 | _titleLabel.font = [UIFont systemFontOfSize:16.0f]; 33 | _titleLabel.textColor = [UIColor whiteColor]; 34 | [_backGroundView addSubview:_titleLabel]; 35 | 36 | _summaryLabel = [[UILabel alloc]init]; 37 | _summaryLabel.font = [UIFont systemFontOfSize:14.0f]; 38 | _summaryLabel.textColor = [UIColor whiteColor]; 39 | [_backGroundView addSubview:_summaryLabel]; 40 | 41 | [self loadAutoLayout]; 42 | } 43 | return self; 44 | } 45 | 46 | 47 | -(void)loadAutoLayout{ 48 | _centerConsArray = [NSMutableArray array]; 49 | 50 | [_backGroundView alignTop:@"5" leading:@"12" bottom:@"-5" trailing:@"-12" toView:_backGroundView.superview]; 51 | 52 | [_logoImageView alignCenterYWithView:_logoImageView.superview predicate:@"0"]; 53 | [_logoImageView constrainWidth:@"40" height:@"40"]; 54 | [_logoImageView alignLeadingEdgeWithView:_logoImageView.superview predicate:@"10"]; 55 | 56 | [_titleLabel constrainLeadingSpaceToView:_logoImageView predicate:@"10"]; 57 | [_titleLabel alignTrailingEdgeWithView:_titleLabel.superview predicate:@"-5"]; 58 | 59 | [_summaryLabel constrainLeadingSpaceToView:_logoImageView predicate:@"10"]; 60 | [_summaryLabel alignTrailingEdgeWithView:_summaryLabel.superview predicate:@"-5"]; 61 | } 62 | 63 | -(void)reload:(FeedEntity *)feed{ 64 | [_logoImageView net_sd_setImageWithURL:[NSURL URLWithString:feed.favicon] placeholderImage:[UIImage imageNamed:@"rssIcon"]]; 65 | 66 | _titleLabel.text = [feed.title replace:RX(@"\ue40a|\ue40b") with:@""]; 67 | 68 | [_titleLabel.superview removeConstraints:_centerConsArray]; 69 | if(feed.summary.isNotEmpty){ 70 | [_centerConsArray addObjectsFromArray: 71 | [_titleLabel alignCenterYWithView:_titleLabel.superview predicate:@"-10"]]; 72 | [_centerConsArray addObjectsFromArray: 73 | [_summaryLabel alignCenterYWithView:_summaryLabel.superview predicate:@"10"]]; 74 | 75 | _summaryLabel.text = [feed.summary replace:RX(@"\ue40a|\ue40b") with:@""]; 76 | _summaryLabel.hidden = NO; 77 | }else{ 78 | _summaryLabel.text = @""; 79 | _summaryLabel.hidden = YES; 80 | [_centerConsArray addObjectsFromArray: 81 | [_titleLabel alignCenterYWithView:_titleLabel.superview predicate:@"0"]]; 82 | } 83 | } 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/RssCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // RssCell.h 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-20. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FeedRssEntity.h" 11 | #import "ALBaseCell.h" 12 | 13 | @interface RssCell : EzTableViewCell 14 | -(void)reloadRss:(FeedRssEntity *)rss; 15 | @end 16 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/RssCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // RssCell.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-20. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "RssCell.h" 10 | 11 | @interface RssCell() 12 | @property(nonatomic,retain)UIImageView *feedImage; 13 | @property(nonatomic,retain)UILabel *feedTitle; 14 | @property(nonatomic,retain)UILabel *rssTitle; 15 | @property(nonatomic,retain)UILabel *summary; 16 | @property(nonatomic,retain)UILabel *time; 17 | @property(nonatomic,retain)UIImageView *rssImageView; 18 | @end 19 | 20 | @implementation RssCell 21 | 22 | -(void)commonInit{ 23 | [super commonInit]; 24 | 25 | self.accessoryType = UITableViewCellAccessoryNone; 26 | self.selectionStyle = UITableViewCellSelectionStyleNone; 27 | 28 | _rssImageView = [[UIImageView alloc]init]; 29 | _rssImageView.contentMode = UIViewContentModeScaleAspectFill; 30 | _rssImageView.clipsToBounds = YES; 31 | _rssImageView.layer.cornerRadius = 5; 32 | [self.contentView addSubview:_rssImageView]; 33 | 34 | UIView *blurView = [[UIView alloc]init]; 35 | blurView.backgroundColor = [UIColor blackColor]; 36 | blurView.alpha = 0.4f; 37 | [_rssImageView addSubview:blurView]; 38 | [blurView alignToView:_rssImageView]; 39 | 40 | _feedTitle = [[UILabel alloc]init]; 41 | _feedTitle.textAlignment = NSTextAlignmentLeft; 42 | _feedTitle.font = [UIFont systemFontOfSize:12.0f]; 43 | _feedTitle.textColor = [UIColor whiteColor]; 44 | [self.contentView addSubview:_feedTitle]; 45 | 46 | _feedImage = [[UIImageView alloc]init]; 47 | _feedImage.layer.masksToBounds = YES; 48 | _feedImage.layer.cornerRadius = 2; 49 | [self.contentView addSubview:_feedImage]; 50 | 51 | 52 | _time = [[UILabel alloc]init]; 53 | _time.textAlignment = NSTextAlignmentRight; 54 | _time.font = [UIFont systemFontOfSize:12.0f]; 55 | _time.textColor = [UIColor whiteColor]; 56 | [self.contentView addSubview:_time]; 57 | 58 | 59 | _rssTitle = [[TTTAttributedLabel alloc]initWithFrame:CGRectZero]; 60 | 61 | _rssTitle.numberOfLines = 0; 62 | _rssTitle.lineBreakMode = NSLineBreakByWordWrapping|NSLineBreakByTruncatingTail; 63 | _rssTitle.textAlignment = NSTextAlignmentLeft; 64 | _rssTitle.font = [UIFont fontWithName:XinGothic size:18.0f]; 65 | _rssTitle.textColor = [UIColor whiteColor]; 66 | [self.contentView addSubview:_rssTitle]; 67 | 68 | [self loadAutolayout]; 69 | } 70 | 71 | -(void)loadAutolayout{ 72 | 73 | [_rssImageView alignTop:@"3" leading:@"5" bottom:@"-3" trailing:@"-5" toView:_rssImageView.superview]; 74 | // [_rssImageView constrainHeight:@"200@999"]; 75 | 76 | [_feedImage alignLeadingEdgeWithView:_feedImage.superview predicate:@"15"]; 77 | [_feedImage alignTopEdgeWithView:_feedImage.superview predicate:@"15"]; 78 | [_feedImage constrainWidth:@"16" height:@"16@999"]; 79 | 80 | [_feedTitle constrainLeadingSpaceToView:_feedImage predicate:@"5"]; 81 | [_feedTitle alignCenterYWithView:_feedImage predicate:@"0"]; 82 | [_feedTitle constrainHeight:@"16@999"]; 83 | 84 | 85 | [_time alignTopEdgeWithView:_feedTitle predicate:@"0"]; 86 | [_time alignTrailingEdgeWithView:_time.superview predicate:@"-15"]; 87 | [_time constrainHeight:@"16@999"]; 88 | 89 | [_rssTitle alignCenterYWithView:_rssTitle.superview predicate:@"0"]; 90 | [_rssTitle alignLeading:@"15" trailing:@"-15" toView:_rssTitle.superview]; 91 | } 92 | 93 | -(void)reloadRss:(FeedRssEntity *)feedRss{ 94 | RssEntity *rss = feedRss.rss; 95 | FeedEntity *feed = feedRss.feed; 96 | [_feedImage net_sd_setImageWithURL:[NSURL URLWithString:feed.favicon] placeholderImage: 97 | [[UIImage imageNamed:@"rssIcon"] tintWithColor:[UIColor whiteColor]]]; 98 | 99 | _time.text = rss.date; 100 | _feedTitle.text = [feed.title replace:RX(@"\ue40a|\ue40b") with:@""]; 101 | _rssTitle.text = [rss.title replace:RX(@"\ue40a|\ue40b") with:@""]; 102 | 103 | 104 | self.rssImageView.backgroundColor = [UIColor randomFlatColor]; 105 | if(rss.image.isNotEmpty){ 106 | [_rssImageView net_sd_setImageWithURL:[NSURL URLWithString:rss.image]]; 107 | }else{ 108 | _rssImageView.image = nil; 109 | } 110 | } 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/RssDetailScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // RssDetailScene.h 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-21. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Scene.h" 10 | #import "FeedRssEntity.h" 11 | 12 | @interface RssDetailScene : Scene 13 | @property(nonatomic,retain)FeedRssEntity *feedRss; 14 | @end 15 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/RssDetailScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // rssDetailScene.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-21. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "RssDetailScene.h" 10 | #import "TOWebViewController.h" 11 | 12 | @interface RssDetailScene () 13 | @property (strong, nonatomic) UIWebView *webView; 14 | @property(nonatomic,retain)NSURL *url; 15 | @property(nonatomic,retain)NSURLRequest *req; 16 | @end 17 | 18 | @implementation RssDetailScene 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | self.title = _feedRss.rss.title; 23 | self.webView = [[UIWebView alloc]init]; 24 | self.webView.delegate = self; 25 | 26 | [self.view addSubview:self.webView]; 27 | [self.webView alignToView:self.view]; 28 | 29 | self.webView.backgroundColor = [UIColor flatWhiteColor]; 30 | _webView.scalesPageToFit = YES; 31 | UIButton *leftbutton = [IconFont buttonWithIcon:[IconFont icon:@"fa_chevron_left" fromFont:fontAwesome] fontName:fontAwesome size:24.0f color:[UIColor whiteColor]]; 32 | [self showBarButton:NAV_LEFT button:leftbutton]; 33 | 34 | [self loadHTML:_feedRss.rss]; 35 | } 36 | 37 | - (void)didReceiveMemoryWarning { 38 | [super didReceiveMemoryWarning]; 39 | // Dispose of any resources that can be recreated. 40 | } 41 | 42 | -(void)rightButtonTouch{ 43 | 44 | [self presentWebView:_url]; 45 | } 46 | 47 | - (void)loadHTML:(RssEntity*)rss 48 | { 49 | if(!rss.isNotEmpty) return; 50 | self.title = rss.title; 51 | 52 | NSString *detailString = [NSMutableString stringFromResFile:@"detail.html" encoding:NSUTF8StringEncoding]; 53 | 54 | detailString = [detailString replace:RX(@"#title#") with:rss.title]; 55 | if(rss.link.isNotEmpty){ 56 | _url = [NSURL URLWithString:rss.link]; 57 | UIButton *rightbutton = [IconFont buttonWithIcon:[IconFont icon:@"fa_external_link" fromFont:fontAwesome] fontName:fontAwesome size:24.0f color:[UIColor whiteColor]]; 58 | [self showBarButton:NAV_RIGHT button:rightbutton]; 59 | 60 | detailString = [detailString replace:RX(@"#link#") with:_feedRss.feed.openUrl]; 61 | }else{ 62 | detailString = [detailString replace:RX(@"href=\"#link#\"") with:@""]; 63 | } 64 | detailString = [detailString replace:RX(@"#author#") with:rss.author]; 65 | detailString = [detailString replace:RX(@"#publishDate#") with:rss.date]; 66 | detailString = [detailString replace:RX(@"#content#") with:rss.content]; 67 | [_webView loadHTMLString:detailString baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]]; 68 | } 69 | 70 | -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ 71 | if (navigationType == UIWebViewNavigationTypeLinkClicked) { 72 | 73 | UIViewController *controller= [UIViewController initFromURL:request.URL fromConfig:[URLManager manager].config]; 74 | if([controller isKindOfClass:[TOWebViewController class]]){ 75 | [(TOWebViewController *)controller setButtonTintColor:[UIColor flatDarkOrangeColor]]; 76 | [(TOWebViewController *)controller setLoadingBarTintColor:[UIColor flatDarkGreenColor]]; 77 | [self.navigationController pushViewController:controller animated:YES]; 78 | }else{ 79 | [self.navigationController pushViewController:controller animated:YES]; 80 | } 81 | return NO; 82 | } 83 | return YES; 84 | } 85 | 86 | /** 87 | * 打开一个webview 88 | * 89 | * @param url NSURL 90 | */ 91 | -(void)presentWebView:(NSURL *)url{ 92 | TOWebViewController *webViewController = [[TOWebViewController alloc] initWithURL:url]; 93 | [webViewController setButtonTintColor:[UIColor flatDarkOrangeColor]]; 94 | [webViewController setLoadingBarTintColor:[UIColor flatDarkGreenColor]]; 95 | [self.navigationController pushViewController:webViewController animated:YES]; 96 | } 97 | @end 98 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/RssListScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // RssListScene.h 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-19. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Scene.h" 10 | 11 | @interface RssListScene : Scene 12 | @end 13 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/RssListScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // RssListScene.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-19. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "RssListScene.h" 10 | #import "RssCell.h" 11 | #import "RssDetailScene.h" 12 | #import "FeedSceneModel.h" 13 | #import "RssListSceneModel.h" 14 | #import "WebDetailScene.h" 15 | #import "ActionSceneModel.h" 16 | #import "AddFeedRequest.h" 17 | 18 | @interface RssListScene () 19 | @property (nonatomic,strong)RssListSceneModel *rssSceneModel; 20 | @property (strong, nonatomic) SceneTableView *tableView; 21 | @property (strong,nonatomic)FeedEntity *feed; 22 | @end 23 | 24 | @implementation RssListScene 25 | 26 | - (void)viewDidLoad { 27 | [super viewDidLoad]; 28 | self.view.backgroundColor = [UIColor whiteColor]; 29 | self.title = self.params[@"title"]; 30 | UIButton *leftbutton = [IconFont buttonWithIcon:[IconFont icon:@"fa_chevron_left" fromFont:fontAwesome] fontName:fontAwesome size:24.0f color:[UIColor whiteColor]]; 31 | [self showBarButton:NAV_LEFT button:leftbutton]; 32 | 33 | 34 | self.tableView = [[SceneTableView alloc]init]; 35 | self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 36 | self.tableView.delegate = self; 37 | self.tableView.dataSource = self; 38 | self.tableView.rowHeight = 210.0f; 39 | [self addSubView:self.tableView extend:EXTEND_TOP]; 40 | [self.tableView registerClass:[RssCell class] forCellReuseIdentifier:@"RssCell"]; 41 | 42 | _rssSceneModel = [RssListSceneModel SceneModel]; 43 | _rssSceneModel.request.feedId = self.params[@"id"]; 44 | @weakify(self); 45 | [self.tableView addPullToRefreshWithActionHandler:^{ 46 | @strongify(self); 47 | self.rssSceneModel.request.page = @1; 48 | self.rssSceneModel.request.requestNeedActive = YES; 49 | }]; 50 | 51 | [self.tableView addInfiniteScrollingWithActionHandler:^{ 52 | @strongify(self); 53 | self.rssSceneModel.request.page = [self.rssSceneModel.request.page increase:@1]; 54 | self.rssSceneModel.request.requestNeedActive = YES; 55 | }]; 56 | 57 | [[RACObserve(self.rssSceneModel, rssList) 58 | filter:^BOOL(RssList* value) { 59 | return value !=nil; 60 | }] 61 | subscribeNext:^(RssList *value) { 62 | @strongify(self); 63 | self.rssSceneModel.dataArray = [value.pagination 64 | success:self.rssSceneModel.dataArray 65 | newArray:value.list]; 66 | self.rssSceneModel.request.page = value.pagination.page; 67 | [self.tableView reloadData]; 68 | [self.tableView endAllRefreshingWithIntEnd:value.pagination.isEnd.integerValue]; 69 | }]; 70 | 71 | [[RACObserve(self.rssSceneModel.request, state) 72 | filter:^BOOL(NSNumber *state) { 73 | @strongify(self); 74 | return self.rssSceneModel.request.failed; 75 | }] 76 | subscribeNext:^(id x) { 77 | @strongify(self); 78 | self.rssSceneModel.request.page = self.rssSceneModel.rssList.pagination.page?:@1; 79 | [self.tableView endAllRefreshingWithIntEnd:self.rssSceneModel.rssList.pagination.isEnd.integerValue]; 80 | }]; 81 | 82 | [self.tableView triggerPullToRefresh]; 83 | [self loadHud:self.view]; 84 | } 85 | 86 | -(void)rightButtonTouch{ 87 | AddFeedRequest *req = [AddFeedRequest Request]; 88 | req.feedUrl = _feed.link; 89 | req.feedType = _feed.feedType; 90 | 91 | [self showHudIndeterminate:@"正在加载"]; 92 | [[ActionSceneModel sharedInstance] sendRequest:req success:^{ 93 | [self hideHudSuccess:@"订阅成功"]; 94 | } error:^{ 95 | [self hideHudFailed:@"订阅失败"]; 96 | }]; 97 | } 98 | 99 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 100 | return self.rssSceneModel.dataArray.count; 101 | } 102 | 103 | - (UITableViewCell *)tableView:(SceneTableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 104 | RssCell *cell = [tableView dequeueReusableCellWithIdentifier:@"RssCell" forIndexPath:indexPath]; 105 | FeedRssEntity *feedRss = [self.rssSceneModel.dataArray objectAtIndex:indexPath.row]; 106 | if(!_feed.isNotEmpty && feedRss.feed.isNotEmpty){ 107 | _feed = feedRss.feed; 108 | [self showBarButton:NAV_RIGHT title:@"订阅" fontColor:[UIColor whiteColor]]; 109 | } 110 | [cell reloadRss:feedRss]; 111 | return cell; 112 | } 113 | 114 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 115 | FeedRssEntity *feedRss = [self.rssSceneModel.dataArray objectAtIndex:indexPath.row]; 116 | 117 | if(feedRss.feed.feedType.integerValue == 0){ 118 | RssDetailScene* scene = [[RssDetailScene alloc]init]; 119 | scene.feedRss = feedRss; 120 | [self.navigationController pushViewController:scene animated:YES]; 121 | }else{ 122 | WebDetailScene* scene = [[WebDetailScene alloc]init]; 123 | scene.feedRss = feedRss; 124 | [self.navigationController pushViewController:scene animated:YES]; 125 | } 126 | } 127 | @end 128 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/SquareScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // SquareScene.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/6. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Scene.h" 10 | 11 | @interface SquareScene : Scene 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/SquareScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // SquareScene.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/6. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SquareScene.h" 10 | #import "RssCell.h" 11 | #import "RssDetailScene.h" 12 | #import 13 | #import "WebDetailScene.h" 14 | #import "RssListScene.h" 15 | #import "AddScene.h" 16 | #import "RDNavigationController.h" 17 | #import "SquareTableView.h" 18 | #import "TagListRequest.h" 19 | #import "ActionSceneModel.h" 20 | 21 | @interface SquareScene () 22 | 23 | @property (nonatomic, strong) HTHorizontalSelectionList *selectionList; 24 | @property (strong, nonatomic) SceneScrollView *scrollView; 25 | @property (nonatomic, strong) NSMutableArray *tagList; 26 | @end 27 | 28 | @implementation SquareScene 29 | 30 | - (void)viewDidLoad { 31 | [super viewDidLoad]; 32 | self.title = @"易阅"; 33 | UIButton *rssbutton = [IconFont buttonWithIcon:[IconFont icon:@"fa_rss" fromFont:fontAwesome] fontName:fontAwesome size:24.0f color:[UIColor whiteColor]]; 34 | [self showBarButton:NAV_RIGHT button:rssbutton]; 35 | 36 | 37 | self.selectionList = [[HTHorizontalSelectionList alloc] init]; 38 | self.selectionList.delegate = self; 39 | self.selectionList.dataSource = self; 40 | [self.selectionList setTitleColor:[UIColor flatDarkOrangeColor] forState:UIControlStateSelected]; 41 | self.selectionList.selectionIndicatorColor = [UIColor flatDarkOrangeColor]; 42 | self.selectionList.bottomTrimColor = [UIColor flatDarkOrangeColor]; 43 | [self.view addSubview:self.selectionList]; 44 | [self.selectionList alignTop:@"0" leading:@"0" bottom:nil trailing:@"0" toView:self.selectionList.superview]; 45 | [self.selectionList constrainHeight:@"40"]; 46 | 47 | 48 | self.scrollView = [[SceneScrollView alloc]init]; 49 | self.scrollView.backgroundColor = [UIColor whiteColor]; 50 | self.scrollView.delegate = self; 51 | self.scrollView.pagingEnabled = YES; 52 | self.scrollView.showsHorizontalScrollIndicator = NO; 53 | self.scrollView.showsVerticalScrollIndicator = NO; 54 | self.scrollView.bounces = NO; 55 | [self.view addSubview:self.scrollView]; 56 | [self.scrollView addHorizontalContentView]; 57 | [self.scrollView horizontalConstrainTopSpaceToView:self.selectionList predicate:@"0"]; 58 | [self.scrollView horizontalAlignBottomWithView:self.scrollView.superview predicate:@"0"]; 59 | [self.scrollView alignLeading:@"0" trailing:@"0" toView:self.scrollView.superview]; 60 | 61 | 62 | @weakify(self); 63 | TagListRequest *req = [TagListRequest Request]; 64 | [[ActionSceneModel sharedInstance] sendRequest:req success:^{ 65 | @strongify(self); 66 | self.tagList = [req.output objectAtPath:@"Data/list"]; 67 | NSUInteger count = self.tagList.count; 68 | if(count>0){ 69 | [self.selectionList reloadData]; 70 | [self.tagList enumerateObjectsUsingBlock:^(NSString *title, NSUInteger idx, BOOL *stop) { 71 | SquareTableView *sqTableView = [[SquareTableView alloc]init]; 72 | [self.scrollView addHorizontalSubView:sqTableView atIndex:idx]; 73 | if(idx == count-1){ 74 | [self.scrollView endWithHorizontalView:sqTableView]; 75 | } 76 | [sqTableView addPullRefreshWithTagName:title]; 77 | }]; 78 | } 79 | } error:nil]; 80 | 81 | } 82 | 83 | - (void)didReceiveMemoryWarning { 84 | [super didReceiveMemoryWarning]; 85 | // Dispose of any resources that can be recreated. 86 | } 87 | 88 | -(void)rightButtonTouch{ 89 | RDNavigationController *nav = [[RDNavigationController alloc]initWithRootViewController:[[AddScene alloc]init]]; 90 | [self presentViewController:nav animated:YES completion:nil]; 91 | } 92 | 93 | 94 | #pragma mark - HTHorizontalSelectionListDataSource Protocol Methods 95 | 96 | - (NSInteger)numberOfItemsInSelectionList:(HTHorizontalSelectionList *)selectionList { 97 | return self.tagList.count; 98 | } 99 | 100 | - (NSString *)selectionList:(HTHorizontalSelectionList *)selectionList titleForItemWithIndex:(NSInteger)index { 101 | 102 | return self.tagList[index]; 103 | } 104 | 105 | #pragma mark - HTHorizontalSelectionListDelegate Protocol Methods 106 | 107 | - (void)selectionList:(HTHorizontalSelectionList *)selectionList didSelectButtonWithIndex:(NSInteger)index { 108 | [self.scrollView scrollRectToVisible:CGRectMake(self.scrollView.width * index, 0, self.scrollView.width, self.scrollView.height) animated:YES]; 109 | } 110 | 111 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 112 | CGFloat pageWidth = scrollView.frame.size.width; 113 | NSInteger index = scrollView.contentOffset.x / pageWidth; 114 | 115 | [self.selectionList setSelectedButtonIndex:index animated:YES]; 116 | } 117 | @end 118 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/WeChatListScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // WeChatListScene.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/5. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Scene.h" 10 | 11 | @interface WeChatListScene : Scene 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/Main/WeChatListScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // WeChatListScene.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/5. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "WeChatListScene.h" 10 | #import "WeChatSceneModel.h" 11 | #import "FeedCell.h" 12 | #import "RssListScene.h" 13 | #import "AddFeedRequest.h" 14 | #import "ActionSceneModel.h" 15 | #import "UIColor+RSS.h" 16 | 17 | @interface WeChatListScene () 18 | @property(nonatomic,retain)SceneTableView *tableView; 19 | @property(nonatomic,retain)WeChatSceneModel *sceneModel; 20 | @end 21 | 22 | @implementation WeChatListScene 23 | 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | self.sceneModel = [WeChatSceneModel SceneModel]; 27 | self.sceneModel.request.query = self.title; 28 | 29 | self.tableView = [[SceneTableView alloc]init]; 30 | 31 | self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 32 | self.tableView.delegate = self; 33 | self.tableView.dataSource = self; 34 | [self.view addSubview:self.tableView]; 35 | [self.tableView alignToView:self.view]; 36 | [self.tableView registerClass:[FeedCell class] forCellReuseIdentifier:@"FeedCell"]; 37 | 38 | 39 | @weakify(self); 40 | 41 | [self.tableView addPullToRefreshWithActionHandler:^{ 42 | @strongify(self); 43 | self.sceneModel.request.page = @1; 44 | self.sceneModel.request.requestNeedActive = YES; 45 | }]; 46 | 47 | [self.tableView addInfiniteScrollingWithActionHandler:^{ 48 | @strongify(self); 49 | self.sceneModel.request.page = [self.sceneModel.request.page increase:@1]; 50 | self.sceneModel.request.requestNeedActive = YES; 51 | }]; 52 | 53 | [[RACObserve(self.sceneModel, searchList) 54 | filter:^BOOL(FeedList* value) { 55 | return value !=nil; 56 | }] 57 | subscribeNext:^(FeedList *value) { 58 | @strongify(self); 59 | self.sceneModel.dataArray = [value.pagination 60 | success:self.sceneModel.dataArray 61 | newArray:value.list]; 62 | self.sceneModel.request.page = value.pagination.page; 63 | [self.tableView reloadData]; 64 | [self.tableView endAllRefreshingWithIntEnd:value.pagination.isEnd.integerValue]; 65 | }]; 66 | 67 | [[RACObserve(self.sceneModel.request, state) 68 | filter:^BOOL(NSNumber *state) { 69 | @strongify(self); 70 | return self.sceneModel.request.failed; 71 | }] 72 | subscribeNext:^(id x) { 73 | @strongify(self); 74 | self.sceneModel.request.page = self.sceneModel.searchList.pagination.page?:@1; 75 | [self.tableView endAllRefreshingWithIntEnd:self.sceneModel.searchList.pagination.isEnd.integerValue]; 76 | }]; 77 | 78 | 79 | [self loadHud:self.view]; 80 | [self.tableView triggerPullToRefresh]; 81 | 82 | // Do any additional setup after loading the view. 83 | } 84 | 85 | - (void)didReceiveMemoryWarning { 86 | [super didReceiveMemoryWarning]; 87 | // Dispose of any resources that can be recreated. 88 | } 89 | 90 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 91 | return 84; 92 | } 93 | 94 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 95 | return self.sceneModel.dataArray.count; 96 | } 97 | 98 | - (FeedCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 99 | FeedCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FeedCell" forIndexPath:indexPath]; 100 | cell.backGroundView.backgroundColor = [UIColor colorAtIndex:indexPath.row]; 101 | FeedEntity *feed = [self.sceneModel.dataArray objectAtIndex:indexPath.row]; 102 | [cell reload:feed]; 103 | [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; 104 | [cell setAccessoryType:UITableViewCellAccessoryNone]; 105 | return cell; 106 | } 107 | 108 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 109 | FeedEntity *feed = [self.sceneModel.dataArray objectAtIndex:indexPath.row]; 110 | AddFeedRequest *req = [AddFeedRequest Request]; 111 | req.feedUrl = feed.link; 112 | req.feedType = @1; 113 | 114 | [self showHudIndeterminate:@"加载中..."]; 115 | [[ActionSceneModel sharedInstance] sendRequest:req success:^{ 116 | [self hideHud]; 117 | FeedEntity *feed = [[FeedEntity alloc]initWithDictionary:[req.output objectAtPath:@"Data/feed"] error:nil]; 118 | [URLManager pushURLString:feed.openUrl animated:YES]; 119 | } error:^{ 120 | [self hideHudFailed:req.message]; 121 | }]; 122 | 123 | } 124 | 125 | 126 | @end 127 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/MineScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // MineScene.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/6. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Scene.h" 10 | 11 | @interface MineScene : Scene 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/MineScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // MineScene.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/6. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "MineScene.h" 10 | 11 | @interface MineScene () 12 | @property (strong, nonatomic) SceneTableView *tableView; 13 | @property(strong,nonatomic)NSArray *dataArray; 14 | @end 15 | 16 | @implementation MineScene 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | self.title = @"我的"; 21 | 22 | _dataArray = @[@[@{@"title":@"账号",@"link":@"easyrss://fav"}], 23 | @[@{@"title":@"订阅频道",@"link":@"easyrss://fav"}, 24 | @{@"title":@"订阅话题",@"link":@"easyrss://fav"}, 25 | @{@"title":@"收藏文章",@"link":@"easyrss://fav"}], 26 | @[@{@"title":@"设置",@"link":@"easyrss://setting"}]]; 27 | self.tableView = [[SceneTableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped]; 28 | self.tableView.backgroundColor = [UIColor colorWithString:@"#EFEFF4"]; 29 | self.tableView.rowHeight = 44.0f; 30 | self.tableView.delegate = self; 31 | self.tableView.dataSource = self; 32 | [self addSubView:self.tableView extend:EXTEND_TOP]; 33 | [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"]; 34 | // Do any additional setup after loading the view. 35 | } 36 | 37 | - (void)didReceiveMemoryWarning { 38 | [super didReceiveMemoryWarning]; 39 | // Dispose of any resources that can be recreated. 40 | } 41 | 42 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 43 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath]; 44 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 45 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 46 | cell.textLabel.text = [[_dataArray objectAtIndexPath:indexPath] objectForKey:@"title"]; 47 | return cell; 48 | } 49 | 50 | -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ 51 | return _dataArray.count; 52 | } 53 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 54 | NSArray *array = [_dataArray objectAtIndex:section]; 55 | return array.count; 56 | } 57 | 58 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 59 | NSString *link = [[_dataArray objectAtIndexPath:indexPath] objectForKey:@"link"]; 60 | [URLManager pushURLString:link animated:YES]; 61 | } 62 | 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/RDNavigationController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RDNavigationController.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/6. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "EZNavigationController.h" 10 | 11 | @interface RDNavigationController : EZNavigationController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/RDNavigationController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RDNavigationController.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/6. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "RDNavigationController.h" 10 | 11 | @interface RDNavigationController () 12 | 13 | @end 14 | 15 | @implementation RDNavigationController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | self.navigationBar.translucent = NO; 20 | // Do any additional setup after loading the view. 21 | } 22 | 23 | - (void)didReceiveMemoryWarning { 24 | [super didReceiveMemoryWarning]; 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | -(UIStatusBarStyle)preferredStatusBarStyle{ 29 | return UIStatusBarStyleLightContent; 30 | } 31 | 32 | /* 33 | #pragma mark - Navigation 34 | 35 | // In a storyboard-based application, you will often want to do a little preparation before navigation 36 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 37 | // Get the new view controller using [segue destinationViewController]. 38 | // Pass the selected object to the new view controller. 39 | } 40 | */ 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/SettingScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // SettingScene.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/18. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Scene.h" 10 | 11 | @interface SettingScene : Scene 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/SettingScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // SettingScene.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/18. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SettingScene.h" 10 | #import "Config.h" 11 | 12 | @interface SettingScene () 13 | @property (strong, nonatomic) SceneTableView *tableView; 14 | @property(strong,nonatomic)NSArray *dataArray; 15 | @end 16 | 17 | @implementation SettingScene 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | self.title = @"我的"; 22 | 23 | self.dataArray = @[@[@{@"title":@"清除缓存",@"link":@"cache://"}], 24 | @[@{@"title":@"省流量模式",@"link":@"switch://noimage"}, 25 | @{@"title":@"夜间模式",@"link":@"switch://nightmode"}]]; 26 | 27 | self.tableView = [[SceneTableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped]; 28 | self.tableView.backgroundColor = [UIColor colorWithString:@"#EFEFF4"]; 29 | self.tableView.rowHeight = 44.0f; 30 | self.tableView.delegate = self; 31 | self.tableView.dataSource = self; 32 | [self addSubView:self.tableView extend:EXTEND_TOP]; 33 | // [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"]; 34 | 35 | // Do any additional setup after loading the view. 36 | } 37 | 38 | - (void)didReceiveMemoryWarning { 39 | [super didReceiveMemoryWarning]; 40 | // Dispose of any resources that can be recreated. 41 | } 42 | 43 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 44 | 45 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; 46 | if(!cell){ 47 | cell= [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cell"]; 48 | } 49 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 50 | NSDictionary *dict = [_dataArray objectAtIndexPath:indexPath]; 51 | cell.textLabel.text = [dict objectForKey:@"title"]; 52 | NSURL *url = [NSURL URLWithString:[dict objectForKey:@"link"]]; 53 | if([url.scheme isEqualToString:@"cache"]){ 54 | cell.detailTextLabel.text = [self getCacheSize]; 55 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 56 | }else if ([url.scheme isEqualToString:@"switch"]){ 57 | UISwitch *sw=[[UISwitch alloc]init]; 58 | if([url.host isEqualToString:@"noimage"]){ 59 | sw.on = [Config sharedInstance].noImageMode.boolValue; 60 | [sw addTarget:self action:@selector(noimage:) forControlEvents:UIControlEventValueChanged]; 61 | }else if ([url.host isEqualToString:@"nightmode"]){ 62 | sw.on = [Config sharedInstance].nightMode.boolValue; 63 | [sw addTarget:self action:@selector(nightmode:) forControlEvents:UIControlEventValueChanged]; 64 | } 65 | cell.accessoryView = sw; 66 | } 67 | return cell; 68 | } 69 | 70 | -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ 71 | return _dataArray.count; 72 | } 73 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 74 | NSArray *array = [_dataArray objectAtIndex:section]; 75 | return array.count; 76 | } 77 | 78 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 79 | NSDictionary *dict = [_dataArray objectAtIndexPath:indexPath]; 80 | NSURL *url = [NSURL URLWithString:[dict objectForKey:@"link"]]; 81 | if([url.scheme isEqualToString:@"cache"]){ 82 | [RMUniversalAlert showAlertInViewController:self withTitle:@"清除缓存" message:@"确认要清除缓存?" cancelButtonTitle:@"取消" destructiveButtonTitle:@"确定" otherButtonTitles:nil tapBlock:^(RMUniversalAlert *alert,NSInteger buttonIndex) { 83 | if (buttonIndex == alert.destructiveButtonIndex) { 84 | [[[TMCache sharedCache] diskCache] removeAllObjects]; 85 | [[SDImageCache sharedImageCache] clearDisk]; 86 | UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath]; 87 | cell.detailTextLabel.text = [self getCacheSize]; 88 | [[DialogUtil sharedInstance] showDlg:self.view textOnly:@"缓存清除成功"]; 89 | } 90 | }]; 91 | } 92 | } 93 | 94 | -(void)noimage:(UISwitch *)sender{ 95 | [Config sharedInstance].noImageMode = [NSNumber numberWithBool: sender.on]; 96 | } 97 | 98 | -(void)nightmode:(UISwitch *)sender{ 99 | [Config sharedInstance].nightMode = [NSNumber numberWithBool: sender.on]; 100 | } 101 | 102 | -(NSString *)getCacheSize{ 103 | 104 | CGFloat num = ([[SDImageCache sharedImageCache] getSize] + [[[TMCache sharedCache] diskCache] byteCount])/1024; 105 | if (num > 1024) { 106 | num = num/1024; 107 | return [NSString stringWithFormat:@"%.1fMB",num]; 108 | }else{ 109 | return [NSString stringWithFormat:@"%.1fKB",num]; 110 | } 111 | } 112 | @end 113 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/SquareFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // SquareFooter.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/3/3. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "PullFooter.h" 10 | 11 | @interface SquareFooter : PullFooter 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/SquareFooter.m: -------------------------------------------------------------------------------- 1 | // 2 | // SquareFooter.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/3/3. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SquareFooter.h" 10 | 11 | @implementation SquareFooter 12 | 13 | -(void)setFooterFrame:(UIScrollView *)scrollView{ 14 | self.frame = CGRectMake(0, 0, scrollView.superview.superview.width, SVInfiniteScrollingViewHeight); 15 | scrollView.infiniteScrollingView.frame = CGRectMake(0, scrollView.superview.height, scrollView.superview.superview.width, SVInfiniteScrollingViewHeight); 16 | @weakify(scrollView); 17 | [[RACObserve(scrollView, contentSize) filter:^BOOL(id value) { 18 | @strongify(scrollView); 19 | return scrollView.contentSize.height>scrollView.bounds.size.height && scrollView.bounds.size.height >0; 20 | }] subscribeNext:^(id x) { 21 | @strongify(scrollView); 22 | scrollView.infiniteScrollingView.frame = CGRectMake(0, scrollView.contentSize.height, scrollView.superview.superview.width, SVInfiniteScrollingViewHeight); 23 | }]; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/SquareHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // SquareHeader.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/3/3. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "PullHeader.h" 10 | 11 | 12 | @interface SquareHeader : PullHeader 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/SquareHeader.m: -------------------------------------------------------------------------------- 1 | // 2 | // SquareHeader.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/3/3. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SquareHeader.h" 10 | 11 | @implementation SquareHeader 12 | 13 | -(void)setHeaderFrame:(UIScrollView *)scrollView{ 14 | self.frame = CGRectMake(0, 0, scrollView.superview.superview.width, SVPullToRefreshViewHeight); 15 | scrollView.pullToRefreshView.frame = CGRectMake(0, - SVPullToRefreshViewHeight, scrollView.superview.superview.width, SVPullToRefreshViewHeight); 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/SquareTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SquareTableView.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/3/2. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SceneTableView.h" 10 | 11 | @interface SquareTableView : SceneTableView 12 | -(void)addPullRefreshWithTagName:(NSString *)tagName; 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/SquareTableView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SquareTableView.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/3/2. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SquareTableView.h" 10 | #import "RecommendSceneModel.h" 11 | #import "RssCell.h" 12 | #import "RssDetailScene.h" 13 | #import "WebDetailScene.h" 14 | #import "SquareHeader.h" 15 | #import "SquareFooter.h" 16 | 17 | @interface SquareTableView() 18 | @property (strong, nonatomic) RecommendSceneModel *sceneModel; 19 | @end 20 | 21 | @implementation SquareTableView 22 | 23 | -(instancetype)init{ 24 | self = [super init]; 25 | if(self){ 26 | self.separatorStyle = UITableViewCellSeparatorStyleNone; 27 | self.delegate = self; 28 | self.dataSource = self; 29 | self.rowHeight = 210.0f; 30 | [self registerClass:[RssCell class] forCellReuseIdentifier:@"RssCell"]; 31 | 32 | _sceneModel = [RecommendSceneModel SceneModel]; 33 | @weakify(self); 34 | 35 | 36 | [[RACObserve(self.sceneModel, list) 37 | filter:^BOOL(RssList* value) { 38 | return value !=nil; 39 | }] 40 | subscribeNext:^(RssList *value) { 41 | @strongify(self); 42 | self.sceneModel.dataArray = [value.pagination 43 | success:self.sceneModel.dataArray 44 | newArray:value.list]; 45 | self.sceneModel.request.page = value.pagination.page; 46 | [self reloadData]; 47 | [self endAllRefreshingWithIntEnd:value.pagination.isEnd.integerValue]; 48 | }]; 49 | 50 | [[RACObserve(self.sceneModel.request, state) 51 | filter:^BOOL(NSNumber *state) { 52 | @strongify(self); 53 | return self.sceneModel.request.failed; 54 | }] 55 | subscribeNext:^(id x) { 56 | @strongify(self); 57 | self.sceneModel.request.page = self.sceneModel.list.pagination.page?:@1; 58 | [self endAllRefreshingWithIntEnd:self.sceneModel.list.pagination.isEnd.integerValue]; 59 | }]; 60 | } 61 | return self; 62 | } 63 | 64 | -(void)addPullRefreshWithTagName:(NSString *)tagName{ 65 | _sceneModel.request.tagName = tagName; 66 | @weakify(self); 67 | 68 | [self addPullToRefreshWithActionHandler:^{ 69 | @strongify(self); 70 | self.sceneModel.request.page = @1; 71 | self.sceneModel.request.requestNeedActive = YES; 72 | } customer:YES]; 73 | [self.pullToRefreshView setCustomView: [[SquareHeader alloc]initWithScrollView:self]]; 74 | 75 | [self addInfiniteScrollingWithActionHandler:^{ 76 | @strongify(self); 77 | self.sceneModel.request.page = [self.sceneModel.request.page increase:@1]; 78 | self.sceneModel.request.requestNeedActive = YES; 79 | } customer:YES]; 80 | 81 | [self.infiniteScrollingView setCustomView:[[SquareFooter alloc] initWithScrollView:self]]; 82 | [self triggerPullToRefresh]; 83 | } 84 | 85 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 86 | return self.sceneModel.dataArray.count; 87 | } 88 | 89 | - (UITableViewCell *)tableView:(SceneTableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 90 | RssCell *cell = [tableView dequeueReusableCellWithIdentifier:@"RssCell" forIndexPath:indexPath]; 91 | 92 | FeedRssEntity *entity = [self.sceneModel.dataArray objectAtIndex:indexPath.row]; 93 | UIButton *_feedButton = [[UIButton alloc]init]; 94 | [cell.contentView addSubview:_feedButton]; 95 | [_feedButton alignTop:@"5" leading:@"5" toView:_feedButton.superview]; 96 | [_feedButton constrainWidth:@"120" height:@"40"]; 97 | 98 | _feedButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) { 99 | [URLManager pushURLString:entity.feed.openUrl animated:YES]; 100 | return [RACSignal empty]; 101 | }]; 102 | [cell reloadRss:entity]; 103 | return cell; 104 | } 105 | 106 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 107 | FeedRssEntity *feedRss = [self.sceneModel.dataArray objectAtIndex:indexPath.row]; 108 | if(feedRss.feed.feedType.integerValue == 0){ 109 | RssDetailScene* scene = [[RssDetailScene alloc]init]; 110 | scene.feedRss = feedRss; 111 | scene.hidesBottomBarWhenPushed = YES; 112 | [URLNavigation pushViewController:scene animated:YES]; 113 | }else{ 114 | WebDetailScene* scene = [[WebDetailScene alloc]init]; 115 | scene.feedRss = feedRss; 116 | scene.hidesBottomBarWhenPushed = YES; 117 | [URLNavigation pushViewController:scene animated:YES]; 118 | } 119 | } 120 | @end 121 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/TabBarController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TabBarController.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/6. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TabBarController : UITabBarController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/TabBarController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TabBarController.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/6. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "TabBarController.h" 10 | #import "TopicScene.h" 11 | 12 | #import "RDNavigationController.h" 13 | #import "SquareScene.h" 14 | #import "MineScene.h" 15 | #import "ChannelScene.h" 16 | 17 | 18 | @interface TabBarController () 19 | @property(nonatomic,retain)RDNavigationController *subscribeNavController; 20 | @property(nonatomic,retain)RDNavigationController *squreNavController; 21 | @property(nonatomic,retain)RDNavigationController *topicNavController; 22 | @property(nonatomic,retain)RDNavigationController *mineNavController; 23 | @end 24 | 25 | @implementation TabBarController 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | self.tabBar.translucent= NO; 30 | 31 | _squreNavController = [[RDNavigationController alloc]initWithRootViewController: 32 | [[SquareScene alloc]init]]; 33 | 34 | _subscribeNavController = [[RDNavigationController alloc]initWithRootViewController: 35 | [[ChannelScene alloc]init]]; 36 | 37 | _topicNavController = [[RDNavigationController alloc]initWithRootViewController: 38 | [[TopicScene alloc]init]]; 39 | 40 | _mineNavController = [[RDNavigationController alloc]initWithRootViewController: 41 | [[MineScene alloc]init]]; 42 | self.viewControllers = [NSArray arrayWithObjects:_squreNavController,_subscribeNavController,_topicNavController,_mineNavController,nil]; 43 | 44 | [_squreNavController.tabBarItem setTitle:@"易阅"]; 45 | [_squreNavController.tabBarItem setImage: 46 | [IconFont imageWithIcon:[IconFont icon:@"ios7Home" fromFont:ionIcons] 47 | fontName:ionIcons iconColor:[UIColor whiteColor] iconSize:25]]; 48 | 49 | [_subscribeNavController.tabBarItem setTitle:@"频道"]; 50 | [_subscribeNavController.tabBarItem setImage: 51 | [IconFont imageWithIcon:[IconFont icon:@"socialRss" fromFont:ionIcons] 52 | fontName:ionIcons iconColor:[UIColor whiteColor] iconSize:25]]; 53 | 54 | 55 | [_topicNavController.tabBarItem setTitle:@"话题"]; 56 | [_topicNavController.tabBarItem setImage: 57 | [IconFont imageWithIcon:[IconFont icon:@"ios7Star" fromFont:ionIcons] 58 | fontName:ionIcons iconColor:[UIColor whiteColor] iconSize:25]]; 59 | 60 | 61 | [_mineNavController.tabBarItem setTitle:@"我的"]; 62 | [_mineNavController.tabBarItem setImage: 63 | [IconFont imageWithIcon:[IconFont icon:@"ios7Person" fromFont:ionIcons] 64 | fontName:ionIcons iconColor:[UIColor whiteColor] iconSize:25]]; 65 | 66 | self.delegate = self; 67 | // Do any additional setup after loading the view. 68 | } 69 | 70 | - (void)didReceiveMemoryWarning { 71 | [super didReceiveMemoryWarning]; 72 | // Dispose of any resources that can be recreated. 73 | } 74 | 75 | /* 76 | #pragma mark - Navigation 77 | 78 | // In a storyboard-based application, you will often want to do a little preparation before navigation 79 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 80 | // Get the new view controller using [segue destinationViewController]. 81 | // Pass the selected object to the new view controller. 82 | } 83 | */ 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/TopicCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicCell.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/15. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TopicCell : UICollectionViewCell 12 | @property(nonatomic,retain)UILabel *textLabel; 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/TopicCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // TopicCell.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/15. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "TopicCell.h" 10 | 11 | @implementation TopicCell 12 | -(instancetype)initWithFrame:(CGRect)frame{ 13 | self = [super initWithFrame:frame]; 14 | if(self){ 15 | _textLabel = [[UILabel alloc]init]; 16 | _textLabel.textColor = [UIColor whiteColor]; 17 | _textLabel.font = [UIFont systemFontOfSize:16.0f]; 18 | [self.contentView addSubview:_textLabel]; 19 | [_textLabel alignCenterWithView:_textLabel.superview]; 20 | } 21 | return self; 22 | } 23 | @end 24 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/TopicListScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicListScene.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/15. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Scene.h" 10 | 11 | @interface TopicListScene : Scene 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/TopicListScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // TopicListScene.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/15. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "TopicListScene.h" 10 | #import "RssCell.h" 11 | #import "RssDetailScene.h" 12 | #import "FeedSceneModel.h" 13 | #import "TopicListSceneModel.h" 14 | #import "WebDetailScene.h" 15 | #import "ActionSceneModel.h" 16 | #import "SubsucribeTopicRequest.h" 17 | 18 | 19 | 20 | @interface TopicListScene () 21 | @property (nonatomic,strong)TopicListSceneModel *rssSceneModel; 22 | @property (strong, nonatomic)SceneTableView *tableView; 23 | @property (strong,nonatomic)FeedEntity *topic; 24 | @end 25 | 26 | @implementation TopicListScene 27 | 28 | - (void)viewDidLoad { 29 | [super viewDidLoad]; 30 | self.view.backgroundColor = [UIColor whiteColor]; 31 | self.title = self.params[@"title"]; 32 | UIButton *leftbutton = [IconFont buttonWithIcon:[IconFont icon:@"fa_chevron_left" fromFont:fontAwesome] fontName:fontAwesome size:24.0f color:[UIColor whiteColor]]; 33 | [self showBarButton:NAV_LEFT button:leftbutton]; 34 | [self showBarButton:NAV_RIGHT title:@"订阅" fontColor:[UIColor whiteColor]]; 35 | 36 | self.tableView = [[SceneTableView alloc]init]; 37 | self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 38 | self.tableView.delegate = self; 39 | self.tableView.dataSource = self; 40 | self.tableView.rowHeight = 210.0f; 41 | [self addSubView:self.tableView extend:EXTEND_TOP]; 42 | [self.tableView registerClass:[RssCell class] forCellReuseIdentifier:@"RssCell"]; 43 | 44 | _rssSceneModel = [TopicListSceneModel SceneModel]; 45 | _rssSceneModel.request.title = self.params[@"title"]; 46 | @weakify(self); 47 | [self.tableView addPullToRefreshWithActionHandler:^{ 48 | @strongify(self); 49 | self.rssSceneModel.request.page = @1; 50 | self.rssSceneModel.request.requestNeedActive = YES; 51 | }]; 52 | 53 | [self.tableView addInfiniteScrollingWithActionHandler:^{ 54 | @strongify(self); 55 | self.rssSceneModel.request.page = [self.rssSceneModel.request.page increase:@1]; 56 | self.rssSceneModel.request.requestNeedActive = YES; 57 | }]; 58 | 59 | [[RACObserve(self.rssSceneModel, rssList) 60 | filter:^BOOL(RssList* value) { 61 | return value !=nil; 62 | }] 63 | subscribeNext:^(RssList *value) { 64 | @strongify(self); 65 | self.rssSceneModel.dataArray = [value.pagination 66 | success:self.rssSceneModel.dataArray 67 | newArray:value.list]; 68 | self.rssSceneModel.request.page = value.pagination.page; 69 | [self.tableView reloadData]; 70 | [self.tableView endAllRefreshingWithIntEnd:value.pagination.isEnd.integerValue]; 71 | }]; 72 | 73 | [[RACObserve(self.rssSceneModel.request, state) 74 | filter:^BOOL(NSNumber *state) { 75 | @strongify(self); 76 | return self.rssSceneModel.request.failed; 77 | }] 78 | subscribeNext:^(id x) { 79 | @strongify(self); 80 | self.rssSceneModel.request.page = self.rssSceneModel.rssList.pagination.page?:@1; 81 | [self.tableView endAllRefreshingWithIntEnd:self.rssSceneModel.rssList.pagination.isEnd.integerValue]; 82 | }]; 83 | 84 | [self.tableView triggerPullToRefresh]; 85 | [self loadHud:self.view]; 86 | // Do any additional setup after loading the view. 87 | } 88 | 89 | - (void)didReceiveMemoryWarning { 90 | [super didReceiveMemoryWarning]; 91 | // Dispose of any resources that can be recreated. 92 | } 93 | 94 | -(void)rightButtonTouch{ 95 | SubsucribeTopicRequest *req = [SubsucribeTopicRequest Request]; 96 | req.title = self.title; 97 | 98 | [self showHudIndeterminate:@"正在加载"]; 99 | [[ActionSceneModel sharedInstance] sendRequest:req success:^{ 100 | [self hideHudSuccess:@"订阅成功"]; 101 | } error:^{ 102 | [self hideHudFailed:@"订阅失败"]; 103 | }]; 104 | } 105 | 106 | 107 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 108 | return self.rssSceneModel.dataArray.count; 109 | } 110 | 111 | - (UITableViewCell *)tableView:(SceneTableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 112 | RssCell *cell = [tableView dequeueReusableCellWithIdentifier:@"RssCell" forIndexPath:indexPath]; 113 | FeedRssEntity *feedRss = [self.rssSceneModel.dataArray objectAtIndex:indexPath.row]; 114 | [cell reloadRss:feedRss]; 115 | return cell; 116 | } 117 | 118 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 119 | FeedRssEntity *feedRss = [self.rssSceneModel.dataArray objectAtIndex:indexPath.row]; 120 | 121 | if(feedRss.feed.feedType.integerValue == 0){ 122 | RssDetailScene* scene = [[RssDetailScene alloc]init]; 123 | scene.feedRss = feedRss; 124 | [self.navigationController pushViewController:scene animated:YES]; 125 | }else{ 126 | WebDetailScene* scene = [[WebDetailScene alloc]init]; 127 | scene.feedRss = feedRss; 128 | [self.navigationController pushViewController:scene animated:YES]; 129 | } 130 | } 131 | 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/TopicScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicScene.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/14. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Scene.h" 10 | 11 | @interface TopicScene : Scene 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/TopicScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // TopicScene.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/14. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "TopicScene.h" 10 | #import "TopicCell.h" 11 | #import 12 | #import "TopicSceneModel.h" 13 | #import "UIColor+RSS.h" 14 | #import "AddScene.h" 15 | #import "RDNavigationController.h" 16 | 17 | @interface TopicScene () 18 | @property (nonatomic, strong) HTHorizontalSelectionList *selectionList; 19 | @property (strong, nonatomic) SceneCollectionView *collectionView; 20 | @property (strong, nonatomic) TopicSceneModel *sceneModel; 21 | @end 22 | 23 | @implementation TopicScene 24 | 25 | - (void)viewDidLoad { 26 | [super viewDidLoad]; 27 | self.title = @"话题"; 28 | self.view.backgroundColor = [UIColor whiteColor]; 29 | 30 | UIButton *rssbutton = [IconFont buttonWithIcon:[IconFont icon:@"fa_rss" fromFont:fontAwesome] fontName:fontAwesome size:24.0f color:[UIColor whiteColor]]; 31 | [self showBarButton:NAV_RIGHT button:rssbutton]; 32 | 33 | 34 | self.selectionList = [[HTHorizontalSelectionList alloc] init]; 35 | self.selectionList.delegate = self; 36 | self.selectionList.dataSource = self; 37 | [self.selectionList setTitleColor:[UIColor flatDarkOrangeColor] forState:UIControlStateSelected]; 38 | self.selectionList.selectionIndicatorColor = [UIColor flatDarkOrangeColor]; 39 | self.selectionList.bottomTrimColor = [UIColor flatDarkOrangeColor]; 40 | [self.view addSubview:self.selectionList]; 41 | [self.selectionList alignTop:@"0" leading:@"0" bottom:nil trailing:@"0" toView:self.selectionList.superview]; 42 | [self.selectionList constrainHeight:@"40"]; 43 | 44 | UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init]; 45 | layout.itemSize = CGSizeMake(95, 60); 46 | layout.scrollDirection = UICollectionViewScrollDirectionVertical; 47 | layout.sectionInset = UIEdgeInsetsMake(5.0, 5.0, 5.0, 5.0); 48 | self.collectionView = [[SceneCollectionView alloc]initWithFrame:CGRectZero 49 | collectionViewLayout:layout]; 50 | 51 | self.collectionView.alwaysBounceVertical = YES; 52 | self.collectionView.backgroundColor = [UIColor whiteColor]; 53 | self.collectionView.delegate = self; 54 | self.collectionView.dataSource = self; 55 | [self.view addSubview:self.collectionView]; 56 | [self.collectionView constrainTopSpaceToView:self.selectionList predicate:@"0"]; 57 | [self.collectionView alignTop:nil leading:@"0" bottom:@"0" trailing:@"0" toView:self.view]; 58 | 59 | [self.collectionView registerClass:[TopicCell class] forCellWithReuseIdentifier:@"TopicCell"]; 60 | 61 | _sceneModel = [TopicSceneModel SceneModel]; 62 | @weakify(self); 63 | self.sceneModel.tagRequest.requestNeedActive = YES; 64 | [[RACObserve(self.sceneModel, tagList) 65 | filter:^BOOL(NSMutableArray* value) { 66 | return value.count >0; 67 | }] 68 | subscribeNext:^(NSMutableArray *value) { 69 | @strongify(self); 70 | [self.selectionList reloadData]; 71 | }]; 72 | 73 | [self.collectionView addPullToRefreshWithActionHandler:^{ 74 | @strongify(self); 75 | self.sceneModel.request.page = @1; 76 | self.sceneModel.request.requestNeedActive = YES; 77 | }]; 78 | 79 | [self.collectionView addInfiniteScrollingWithActionHandler:^{ 80 | @strongify(self); 81 | self.sceneModel.request.page = [self.sceneModel.request.page increase:@1]; 82 | self.sceneModel.request.requestNeedActive = YES; 83 | }]; 84 | 85 | [[RACObserve(self.sceneModel, list) 86 | filter:^BOOL(FeedList* value) { 87 | return value !=nil; 88 | }] 89 | subscribeNext:^(FeedList *value) { 90 | @strongify(self); 91 | self.sceneModel.dataArray = [value.pagination 92 | success:self.sceneModel.dataArray 93 | newArray:value.list]; 94 | self.sceneModel.request.page = value.pagination.page; 95 | [self.collectionView reloadData]; 96 | [self.collectionView endAllRefreshingWithIntEnd:value.pagination.isEnd.integerValue]; 97 | }]; 98 | 99 | [[RACObserve(self.sceneModel.request, state) 100 | filter:^BOOL(NSNumber *state) { 101 | @strongify(self); 102 | return self.sceneModel.request.failed; 103 | }] 104 | subscribeNext:^(id x) { 105 | @strongify(self); 106 | self.sceneModel.request.page = self.sceneModel.list.pagination.page?:@1; 107 | [self.collectionView endAllRefreshingWithIntEnd:self.sceneModel.list.pagination.isEnd.integerValue]; 108 | }]; 109 | [self.collectionView triggerPullToRefresh]; 110 | 111 | // Do any additional setup after loading the view. 112 | } 113 | 114 | - (void)didReceiveMemoryWarning { 115 | [super didReceiveMemoryWarning]; 116 | // Dispose of any resources that can be recreated. 117 | } 118 | -(void)rightButtonTouch{ 119 | RDNavigationController *nav = [[RDNavigationController alloc]initWithRootViewController:[[AddScene alloc]init]]; 120 | [self presentViewController:nav animated:YES completion:nil]; 121 | } 122 | 123 | -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ 124 | return self.sceneModel.dataArray.count; 125 | } 126 | 127 | -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ 128 | TopicCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TopicCell" forIndexPath:indexPath]; 129 | cell.contentView.backgroundColor = [UIColor colorAtIndex:indexPath.row]; 130 | FeedEntity *entity = [self.sceneModel.dataArray safeObjectAtIndex:indexPath.row]; 131 | cell.textLabel.text = entity.title; 132 | return cell; 133 | } 134 | 135 | -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ 136 | FeedEntity *entity = [self.sceneModel.dataArray safeObjectAtIndex:indexPath.row]; 137 | [URLManager pushURLString:entity.openUrl animated:YES]; 138 | } 139 | 140 | #pragma mark - HTHorizontalSelectionListDataSource Protocol Methods 141 | 142 | - (NSInteger)numberOfItemsInSelectionList:(HTHorizontalSelectionList *)selectionList { 143 | return self.sceneModel.tagList.count; 144 | } 145 | 146 | - (NSString *)selectionList:(HTHorizontalSelectionList *)selectionList titleForItemWithIndex:(NSInteger)index { 147 | return self.sceneModel.tagList[index]; 148 | } 149 | 150 | #pragma mark - HTHorizontalSelectionListDelegate Protocol Methods 151 | 152 | - (void)selectionList:(HTHorizontalSelectionList *)selectionList didSelectButtonWithIndex:(NSInteger)index { 153 | [self.sceneModel.request cancle]; 154 | self.sceneModel.request.tagName = self.sceneModel.tagList[index]; 155 | self.sceneModel.request.page = @1; 156 | self.sceneModel.request.requestNeedActive = YES; 157 | } 158 | 159 | @end 160 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/WebDetailScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // WebDetailScene.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/10. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "Scene.h" 10 | 11 | #import "FeedRssEntity.h" 12 | @interface WebDetailScene : Scene 13 | @property(nonatomic,retain)FeedRssEntity *feedRss; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /rssreader/Home/Scene/WebDetailScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // WebDetailScene.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/10. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "WebDetailScene.h" 10 | #import "TOWebViewController.h" 11 | 12 | @interface WebDetailScene () 13 | @property (strong, nonatomic) UIWebView *webView; 14 | @property(nonatomic,retain)NSURL *url; 15 | @property(nonatomic,retain)NSURLRequest *req; 16 | 17 | @end 18 | 19 | @implementation WebDetailScene 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | 24 | self.title = [_feedRss.rss.title replace:RX(@"\ue40a|\ue40b") with:@""]; 25 | 26 | self.webView = [[UIWebView alloc]init]; 27 | self.webView.delegate = self; 28 | 29 | [self.view addSubview:self.webView]; 30 | [self.webView alignToView:self.view]; 31 | 32 | self.webView.backgroundColor = [UIColor flatWhiteColor]; 33 | _webView.scalesPageToFit = YES; 34 | UIButton *leftbutton = [IconFont buttonWithIcon:[IconFont icon:@"fa_chevron_left" fromFont:fontAwesome] fontName:fontAwesome size:24.0f color:[UIColor whiteColor]]; 35 | [self showBarButton:NAV_LEFT button:leftbutton]; 36 | 37 | [_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:_feedRss.rss.link]]]; 38 | } 39 | 40 | - (void)didReceiveMemoryWarning { 41 | [super didReceiveMemoryWarning]; 42 | // Dispose of any resources that can be recreated. 43 | } 44 | 45 | -(void)rightButtonTouch{ 46 | [self presentWebView:_url]; 47 | } 48 | 49 | 50 | -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ 51 | if (navigationType == UIWebViewNavigationTypeLinkClicked) { 52 | UIViewController *controller= [UIViewController initFromURL:request.URL fromConfig:[URLManager manager].config]; 53 | if([controller isKindOfClass:[TOWebViewController class]]){ 54 | [(TOWebViewController *)controller setButtonTintColor:[UIColor flatDarkOrangeColor]]; 55 | [(TOWebViewController *)controller setLoadingBarTintColor:[UIColor flatDarkGreenColor]]; 56 | [URLNavigation pushViewController:controller animated:YES]; 57 | }else{ 58 | [URLNavigation pushViewController:controller animated:YES]; 59 | } 60 | return NO; 61 | } 62 | return YES; 63 | } 64 | 65 | /** 66 | * 打开一个webview 67 | * 68 | * @param url NSURL 69 | */ 70 | -(void)presentWebView:(NSURL *)url{ 71 | TOWebViewController *webViewController = [[TOWebViewController alloc] initWithURL:url]; 72 | [webViewController setButtonTintColor:[UIColor flatDarkOrangeColor]]; 73 | [webViewController setLoadingBarTintColor:[UIColor flatDarkGreenColor]]; 74 | [self.navigationController pushViewController:webViewController animated:YES]; 75 | } 76 | 77 | - (void)webViewDidFinishLoad:(UIWebView *)webView 78 | { 79 | NSString *html = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.innerHTML"]; 80 | RxMatch* match = [html firstMatchWithDetails:RX(@"var\\smsg_source_url\\s=\\s'([^']+)';")]; 81 | if(match && match.groups.count >=2){ 82 | RxMatchGroup *group2 = match.groups[1]; 83 | self.url = [NSURL URLWithString:group2.value]; 84 | UIButton *rightbutton = [IconFont buttonWithIcon:[IconFont icon:@"fa_external_link" fromFont:fontAwesome] fontName:fontAwesome size:24.0f color:[UIColor whiteColor]]; 85 | [self showBarButton:NAV_RIGHT button:rightbutton]; 86 | } 87 | NSString *js = [NSString stringWithFormat: 88 | @"var postuser = document.getElementById(\"post-user\");" 89 | "postuser.parentNode.innerHTML = \"%@%@\";",_feedRss.rss.date,_feedRss.feed.openUrl,_feedRss.feed.title]; 90 | [webView stringByEvaluatingJavaScriptFromString:js]; 91 | } 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/ActionSceneModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ActionSceneModel.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/10. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SceneModel.h" 10 | 11 | @interface ActionSceneModel : SceneModel 12 | + (ActionSceneModel *)sharedInstance; 13 | -(void)sendRequest:(Request *)req 14 | success:(void (^)())successHandler 15 | error:(void (^)())errorHandler; 16 | @end 17 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/ActionSceneModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ActionSceneModel.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/10. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "ActionSceneModel.h" 10 | 11 | @implementation ActionSceneModel 12 | + (ActionSceneModel *)sharedInstance{ 13 | GCDSharedInstance(^{ return [self SceneModel]; }); 14 | } 15 | 16 | -(void)sendRequest:(Request *)req 17 | success:(void (^)())successHandler 18 | error:(void (^)())errorHandler{ 19 | [RACObserve(req, state) //监控 网络请求的状态 20 | subscribeNext:^(NSNumber *state) { 21 | if(req.succeed && successHandler){ 22 | successHandler(); 23 | }else if (req.failed && errorHandler){ 24 | errorHandler(); 25 | } 26 | }]; 27 | [self SEND_NO_CACHE_ACTION:req]; 28 | } 29 | @end 30 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/ChannelSceneModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ChannelSceneModel.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/9. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SceneModel.h" 10 | #import "ChannelRequest.h" 11 | #import "TagListRequest.h" 12 | #import "FeedList.h" 13 | 14 | @interface ChannelSceneModel : SceneModel 15 | @property(nonatomic,retain)ChannelRequest *request; 16 | @property(nonatomic,retain)FeedList *feedList; 17 | @property(nonatomic,retain)NSMutableArray *dataArray; 18 | @end 19 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/ChannelSceneModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ChannelSceneModel.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/9. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "ChannelSceneModel.h" 10 | 11 | @implementation ChannelSceneModel 12 | 13 | /** 14 | * 初始化加载SceneModel 15 | */ 16 | -(void)loadSceneModel{ 17 | [super loadSceneModel]; 18 | [self.action useCache]; 19 | self.feedList = nil; 20 | self.dataArray = [NSMutableArray array]; 21 | @weakify(self); 22 | _request = [ChannelRequest RequestWithBlock:^{ // 初始化请求回调 23 | @strongify(self) 24 | [self SEND_CACHE_ACTION:self.request]; 25 | }]; 26 | 27 | [[RACObserve(self.request, state) //监控 网络请求的状态 28 | filter:^BOOL(NSNumber *state) { //过滤请求状态 29 | @strongify(self); 30 | return self.request.succeed; 31 | }] 32 | subscribeNext:^(NSNumber *state) { 33 | @strongify(self); 34 | NSError *error; 35 | self.feedList = [[FeedList alloc] initWithDictionary:[self.request.output objectAtPath:@"Data"] error:&error];//Model的ORM操作,dictionary to object 36 | }]; 37 | 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/DiscoverySceneModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // DiscoverySceneModel.h 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-24. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SceneModel.h" 10 | 11 | @interface DiscoverySceneModel : SceneModel 12 | @property(nonatomic,retain)NSMutableArray *dataArray; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/DiscoverySceneModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // DiscoverySceneModel.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-24. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "DiscoverySceneModel.h" 10 | 11 | @implementation DiscoverySceneModel 12 | 13 | -(void)loadSceneModel{ 14 | 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/FavSceneModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // FavSceneModel.h 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-24. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SceneModel.h" 10 | #import "Pagination.h" 11 | 12 | @interface FavSceneModel : SceneModel 13 | @property(nonatomic,retain)NSArray *favArray; 14 | @property(nonatomic,retain)Pagination *pagination; 15 | @end 16 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/FavSceneModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // FavSceneModel.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-24. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "FavSceneModel.h" 10 | //#import "Rss.h" 11 | 12 | @implementation FavSceneModel 13 | /** 14 | * 生成单例 15 | * 16 | * @return FeedSceneModel单例 17 | */ 18 | + (instancetype)sharedInstance { 19 | GCDSharedInstance(^{ return [self SceneModel]; }); 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/FeedSceneModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // FeedSceneModel.h 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-18. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SceneModel.h" 10 | #import "FeedListRequest.h" 11 | #import "FeedList.h" 12 | 13 | @interface FeedSceneModel : SceneModel 14 | @property(nonatomic,retain)FeedList *feedList; 15 | @property(nonatomic,retain)FeedListRequest *request; 16 | @property(nonatomic,retain)NSMutableArray *dataArray; 17 | @end 18 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/FeedSceneModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // FeedSceneModel.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-18. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "FeedSceneModel.h" 10 | #import "DataCenter.h" 11 | @interface FeedSceneModel () 12 | @end 13 | 14 | @implementation FeedSceneModel 15 | 16 | /** 17 | * 初始化加载SceneModel 18 | */ 19 | -(void)loadSceneModel{ 20 | [super loadSceneModel]; 21 | [self.action useCache]; 22 | self.feedList = nil; 23 | self.dataArray = [NSMutableArray array]; 24 | @weakify(self); 25 | _request = [FeedListRequest RequestWithBlock:^{ // 初始化请求回调 26 | @strongify(self) 27 | [self SEND_IQ_ACTION:self.request]; 28 | }]; 29 | 30 | 31 | [[RACObserve(self.request, state) //监控 网络请求的状态 32 | filter:^BOOL(NSNumber *state) { //过滤请求状态 33 | @strongify(self); 34 | return self.request.succeed; 35 | }] 36 | subscribeNext:^(NSNumber *state) { 37 | @strongify(self); 38 | NSError *error; 39 | self.feedList = [[FeedList alloc] initWithDictionary:[self.request.output objectForKey:@"Data"] error:&error];//Model的ORM操作,dictionary to object 40 | }]; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/RecommendSceneModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // RecommendSceneModel.h 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-22. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SceneModel.h" 10 | #import "RecommendRequest.h" 11 | #import "RssList.h" 12 | #import "TagListRequest.h" 13 | 14 | @interface RecommendSceneModel : SceneModel 15 | @property(nonatomic,retain)RecommendRequest *request; 16 | @property(nonatomic,retain)RssList *list; 17 | @property(nonatomic,retain)NSMutableArray *dataArray; 18 | @end 19 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/RecommendSceneModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // RecommendSceneModel.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-22. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "RecommendSceneModel.h" 10 | 11 | 12 | @implementation RecommendSceneModel 13 | 14 | /** 15 | * 初始化加载SceneModel 16 | */ 17 | -(void)loadSceneModel{ 18 | [super loadSceneModel]; 19 | [self.action useCache]; 20 | self.list = nil; 21 | self.dataArray = [NSMutableArray array]; 22 | @weakify(self); 23 | _request = [RecommendRequest RequestWithBlock:^{ // 初始化请求回调 24 | @strongify(self) 25 | [self SEND_CACHE_ACTION:self.request]; 26 | }]; 27 | 28 | [[RACObserve(self.request, state) //监控 网络请求的状态 29 | filter:^BOOL(NSNumber *state) { //过滤请求状态 30 | @strongify(self); 31 | return self.request.succeed; 32 | }] 33 | subscribeNext:^(NSNumber *state) { 34 | @strongify(self); 35 | NSError *error; 36 | self.list = [[RssList alloc] initWithDictionary:[self.request.output objectAtPath:@"Data"] error:&error];//Model的ORM操作,dictionary to object 37 | }]; 38 | 39 | 40 | } 41 | @end 42 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/RssListSceneModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // RssListSceneModel.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SceneModel.h" 10 | #import "RssList.h" 11 | #import "RssListRequest.h" 12 | 13 | @interface RssListSceneModel : SceneModel 14 | 15 | @property(nonatomic,retain)RssList *rssList; 16 | @property(nonatomic,retain)RssListRequest *request; 17 | @property(nonatomic,retain)NSMutableArray *dataArray; 18 | @end 19 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/RssListSceneModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // RssListSceneModel.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/4. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "RssListSceneModel.h" 10 | 11 | @implementation RssListSceneModel 12 | /** 13 | * 初始化加载SceneModel 14 | */ 15 | -(void)loadSceneModel{ 16 | [super loadSceneModel]; 17 | [self.action useCache]; 18 | self.rssList = nil; 19 | self.dataArray = [NSMutableArray array]; 20 | @weakify(self); 21 | _request = [RssListRequest RequestWithBlock:^{ // 初始化请求回调 22 | @strongify(self) 23 | [self SEND_IQ_ACTION:self.request]; 24 | }]; 25 | 26 | 27 | [[RACObserve(self.request, state) //监控 网络请求的状态 28 | filter:^BOOL(NSNumber *state) { //过滤请求状态 29 | @strongify(self); 30 | return self.request.succeed; 31 | }] 32 | subscribeNext:^(NSNumber *state) { 33 | @strongify(self); 34 | NSError *error; 35 | self.rssList = [[RssList alloc] initWithDictionary:[self.request.output objectForKey:@"Data"] error:&error];//Model的ORM操作,dictionary to object 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/TopicListSceneModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicListSceneModel.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/15. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SceneModel.h" 10 | #import "TopicDetailRequest.h" 11 | #import "RssList.h" 12 | 13 | @interface TopicListSceneModel : SceneModel 14 | @property(nonatomic,retain)RssList *rssList; 15 | @property(nonatomic,retain)TopicDetailRequest *request; 16 | @property(nonatomic,retain)NSMutableArray *dataArray; 17 | @end 18 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/TopicListSceneModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // TopicListSceneModel.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/15. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "TopicListSceneModel.h" 10 | 11 | @implementation TopicListSceneModel 12 | /** 13 | * 初始化加载SceneModel 14 | */ 15 | -(void)loadSceneModel{ 16 | [super loadSceneModel]; 17 | [self.action useCache]; 18 | self.rssList = nil; 19 | self.dataArray = [NSMutableArray array]; 20 | @weakify(self); 21 | _request = [TopicDetailRequest RequestWithBlock:^{ // 初始化请求回调 22 | @strongify(self) 23 | [self SEND_IQ_ACTION:self.request]; 24 | }]; 25 | 26 | [[RACObserve(self.request, state) //监控 网络请求的状态 27 | filter:^BOOL(NSNumber *state) { //过滤请求状态 28 | @strongify(self); 29 | return self.request.succeed; 30 | }] 31 | subscribeNext:^(NSNumber *state) { 32 | @strongify(self); 33 | NSError *error; 34 | self.rssList = [[RssList alloc] initWithDictionary:[self.request.output objectForKey:@"Data"] error:&error];//Model的ORM操作,dictionary to object 35 | }]; 36 | } 37 | @end 38 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/TopicSceneModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // TopicSceneModel.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/14. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SceneModel.h" 10 | #import "TagListRequest.h" 11 | #import "TopicRecommendRequest.h" 12 | #import "FeedList.h" 13 | 14 | @interface TopicSceneModel : SceneModel 15 | @property(nonatomic,retain)TopicRecommendRequest *request; 16 | @property(nonatomic,retain)TagListRequest *tagRequest; 17 | @property(nonatomic,retain)FeedList *list; 18 | @property(nonatomic,retain)NSMutableArray *tagList; 19 | @property(nonatomic,retain)NSMutableArray *dataArray; 20 | @end 21 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/TopicSceneModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // TopicSceneModel.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/14. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "TopicSceneModel.h" 10 | 11 | @implementation TopicSceneModel 12 | /** 13 | * 初始化加载SceneModel 14 | */ 15 | -(void)loadSceneModel{ 16 | [super loadSceneModel]; 17 | [self.action useCache]; 18 | self.list = nil; 19 | self.tagList = [NSMutableArray array]; 20 | self.dataArray = [NSMutableArray array]; 21 | @weakify(self); 22 | _request = [TopicRecommendRequest RequestWithBlock:^{ // 初始化请求回调 23 | @strongify(self) 24 | [self SEND_CACHE_ACTION:self.request]; 25 | }]; 26 | 27 | [[RACObserve(self.request, state) //监控 网络请求的状态 28 | filter:^BOOL(NSNumber *state) { //过滤请求状态 29 | @strongify(self); 30 | return self.request.succeed; 31 | }] 32 | subscribeNext:^(NSNumber *state) { 33 | @strongify(self); 34 | NSError *error; 35 | self.list = [[FeedList alloc] initWithDictionary:[self.request.output objectAtPath:@"Data"] error:&error];//Model的ORM操作,dictionary to object 36 | }]; 37 | 38 | _tagRequest = [TagListRequest RequestWithBlock:^{ 39 | @strongify(self) 40 | [self SEND_IQ_ACTION:self.tagRequest]; 41 | }]; 42 | 43 | [[RACObserve(self.tagRequest, state) //监控 网络请求的状态 44 | filter:^BOOL(NSNumber *state) { //过滤请求状态 45 | @strongify(self); 46 | return self.tagRequest.succeed; 47 | }] 48 | subscribeNext:^(NSNumber *state) { 49 | @strongify(self); 50 | self.tagList = [self.tagRequest.output objectAtPath:@"Data/list"]; 51 | }]; 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/WeChatSceneModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WeChatSceneModel.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/5. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "SceneModel.h" 10 | #import "SearchWeChatRequest.h" 11 | #import "FeedList.h" 12 | @interface WeChatSceneModel : SceneModel 13 | @property(nonatomic,retain)FeedList *searchList; 14 | @property(nonatomic,retain)SearchWeChatRequest *request; 15 | @property(nonatomic,retain)NSMutableArray *dataArray; 16 | @end 17 | -------------------------------------------------------------------------------- /rssreader/Home/SceneModel/WeChatSceneModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // WeChatSceneModel.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/5. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "WeChatSceneModel.h" 10 | @implementation WeChatSceneModel 11 | /** 12 | * 初始化加载SceneModel 13 | */ 14 | -(void)loadSceneModel{ 15 | [super loadSceneModel]; 16 | [self.action useCache]; 17 | self.searchList = nil; 18 | self.dataArray = [NSMutableArray array]; 19 | @weakify(self); 20 | self.request = [SearchWeChatRequest RequestWithBlock:^{ // 初始化请求回调 21 | @strongify(self) 22 | [self SEND_IQ_ACTION:self.request]; 23 | }]; 24 | 25 | [[RACObserve(self.request, state) //监控 网络请求的状态 26 | filter:^BOOL(NSNumber *state) { //过滤请求状态 27 | @strongify(self); 28 | return self.request.succeed; 29 | }] 30 | subscribeNext:^(NSNumber *state) { 31 | @strongify(self); 32 | NSError *error; 33 | self.searchList = [[FeedList alloc] initWithDictionary:[self.request.output objectForKey:@"Data"] error:&error];//Model的ORM操作,dictionary to object 34 | }]; 35 | 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /rssreader/Home/UIColor+RSS.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+RSS.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/11. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIColor (RSS) 12 | 13 | +(UIColor *)colorAtIndex:(NSUInteger)index; 14 | @end 15 | -------------------------------------------------------------------------------- /rssreader/Home/UIColor+RSS.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+RSS.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/11. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "UIColor+RSS.h" 10 | 11 | @implementation UIColor (RSS) 12 | +(UIColor *)colorAtIndex:(NSUInteger)index{ 13 | NSArray *colors = @[@"#DD544E",@"#FF98A7",@"#72B4D1",@"#4681CF",@"#FFBA4D", 14 | @"#72B4D1",@"#DD544E",@"#FF6F49",@"#535F8B",@"#DF5B56", 15 | @"#FFBA4D",@"#EF5282",@"#DD544E",@"#54C5B4",@"#535F8B"]; 16 | return [UIColor colorWithString:[colors objectAtIndex:index%15]]; 17 | } 18 | @end 19 | -------------------------------------------------------------------------------- /rssreader/Home/UIImageView+Network.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+Network.h 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/18. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImageView (Network) 12 | 13 | - (void)net_sd_setImageWithURL:(NSURL *)url; 14 | - (void)net_sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; 15 | @end 16 | -------------------------------------------------------------------------------- /rssreader/Home/UIImageView+Network.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+Network.m 3 | // rssreader 4 | // 5 | // Created by zhuchao on 15/2/18. 6 | // Copyright (c) 2015年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import "UIImageView+Network.h" 10 | #import "Config.h" 11 | 12 | 13 | @implementation UIImageView (Network) 14 | 15 | -(void)net_sd_setImageWithURL:(NSURL *)url{ 16 | [self net_sd_setImageWithURL:url placeholderImage:nil]; 17 | } 18 | 19 | - (void)net_sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder{ 20 | if([Config sharedInstance].noImageMode.boolValue){ 21 | NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url]; 22 | UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key]; 23 | self.image = lastPreviousCachedImage?:placeholder; 24 | }else{ 25 | [self sd_setImageWithURL:url placeholderImage:placeholder]; 26 | } 27 | } 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /rssreader/Home/URLManage.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | http 6 | TOWebViewController 7 | easyrss 8 | 9 | easyrss://setting 10 | SettingScene 11 | easyrss://topic 12 | TopicListScene 13 | easyrss://fav 14 | FavScene 15 | easyrss://feed 16 | RssListScene 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /rssreader/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /rssreader/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /rssreader/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleLocalizations 14 | 15 | zh_CN 16 | en 17 | 18 | CFBundleName 19 | 易阅 20 | CFBundlePackageType 21 | APPL 22 | CFBundleShortVersionString 23 | 1.4 24 | CFBundleSignature 25 | ???? 26 | CFBundleURLTypes 27 | 28 | 29 | CFBundleTypeRole 30 | Editor 31 | CFBundleURLName 32 | com.08dream.rssreader 33 | CFBundleURLSchemes 34 | 35 | feed 36 | 37 | 38 | 39 | CFBundleVersion 40 | 12 41 | LSRequiresIPhoneOS 42 | 43 | UIBackgroundModes 44 | 45 | fetch 46 | 47 | UILaunchStoryboardName 48 | Launch Screen 49 | UIRequiredDeviceCapabilities 50 | 51 | armv7 52 | 53 | UIStatusBarStyle 54 | UIStatusBarStyleLightContent 55 | UISupportedInterfaceOrientations 56 | 57 | UIInterfaceOrientationPortrait 58 | 59 | UIViewControllerBasedStatusBarAppearance 60 | 61 | NSAppTransportSecurity 62 | 63 | NSAllowsArbitraryLoads 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /rssreader/Supporting Files/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // rssreader 4 | // 5 | // Created by zhuchao on 14-9-7. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIColor+MLPFlatColors.h" 11 | #import "PullFooter.h" 12 | #import "PullHeader.h" 13 | #import "Easy-Extention.h" 14 | #import "UIImageView+Network.h" 15 | 16 | #define DEFAULT_PAGE_SIZE @20 17 | #define XinGothic @"XinGothic-Regular" -------------------------------------------------------------------------------- /rssreader/Supporting Files/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // rssreader 4 | // 5 | // Created by 朱潮 on 14-8-12. 6 | // Copyright (c) 2014年 zhuchao. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | --------------------------------------------------------------------------------