├── .babelrc ├── .gitignore ├── README.md ├── app ├── DevTools.js ├── api │ └── index.js ├── components │ ├── carousel.jsx │ ├── comment-item.jsx │ ├── common-header.jsx │ ├── detail-content.jsx │ ├── detail-header.jsx │ ├── list-default.jsx │ ├── list-header.jsx │ ├── list-item.jsx │ ├── list-theme.jsx │ ├── sidebar.jsx │ └── slider.jsx ├── css │ ├── author.scss │ ├── comments-item.scss │ ├── comments.scss │ ├── common-header.scss │ ├── detail-content.scss │ ├── detail-header.scss │ ├── editor.scss │ ├── list-default.scss │ ├── list-header.scss │ ├── list-item.scss │ ├── list-theme.scss │ ├── main.scss │ ├── recommender.scss │ ├── reset.scss │ ├── section.scss │ ├── sidebar.scss │ ├── slick-theme.scss │ ├── slick.scss │ ├── slider.scss │ ├── swiper-3.3.1.min.css │ └── zhihu_news_detail.scss ├── index.html ├── main.dev.js ├── main.js ├── redux │ ├── action │ │ ├── acitontype.js │ │ └── index.js │ └── reducer │ │ ├── comments.js │ │ ├── detail.js │ │ ├── index.js │ │ ├── list.js │ │ ├── recommender.js │ │ ├── section.js │ │ └── sidebar.js ├── router │ └── index.js ├── util │ ├── ajax.js │ └── filter.js └── view │ ├── author.jsx │ ├── comments.jsx │ ├── detail.jsx │ ├── editor.jsx │ ├── list.jsx │ ├── recommender.jsx │ └── section.jsx ├── build ├── CNAME ├── app.js ├── index.html └── vendors.js ├── package.json └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "react", 5 | "stage-2" 6 | ], 7 | "plugins": [] 8 | } 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | npm-debug.log 4 | .idea/ 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zhihudaily-react 2 | 3 | > A react.js project 4 | 5 | ## 声明 6 | 7 | 本项目所有文字图片等稿件内容均由 [知乎](https://www.zhihu.com/) 提供,获取与共享之行为或有侵犯知乎权益的嫌疑。若被告知需停止共享与使用,本人会及时删除整个项目。 8 | 9 | 请您了解相关情况,并遵守知乎协议。 10 | 11 | ## 同功能vue版项目地址: 12 | 13 | [https://github.com/yatessss/zhihudaily-vue](https://github.com/yatessss/zhihudaily-vue) 14 | 15 | ## 运行截图 16 | 17 | ![](http://7xqch8.com1.z0.glb.clouddn.com/blog_2016_07_picQQ20160708-0.png) 18 | ![](http://7xqch8.com1.z0.glb.clouddn.com/blog_2016_07_picQQ20160708-1.png) 19 | ![](http://7xqch8.com1.z0.glb.clouddn.com/blog_2016_07_picQQ20160708-2.png) 20 | ![](http://7xqch8.com1.z0.glb.clouddn.com/blog_2016_07_picQQ20160708-3.png) 21 | ![](http://7xqch8.com1.z0.glb.clouddn.com/blog_2016_07_picQQ20160708-4.png) 22 | ![](http://7xqch8.com1.z0.glb.clouddn.com/blog_2016_07_picQQ20160708-5.png) 23 | ![](http://7xqch8.com1.z0.glb.clouddn.com/blog_2016_07_picQQ20160708-6.png) 24 | ![](http://7xqch8.com1.z0.glb.clouddn.com/blog_2016_07_picQQ20160708-7.png) 25 | 26 | ## 运行动图 27 | 28 | [播放请点击这里](http://7xqch8.com1.z0.glb.clouddn.com/blog_2016_07_picUntitled11.gif) 29 | 30 | 31 | 32 | ## 在线地址 33 | 34 | 需打开chrome浏览器的手机模拟功能,来获得比较好的浏览效果 35 | 36 | ~~[demo地址]()~~ (域名被回收了,目前还没新的。。请clone后本地运行。。) 37 | 38 | 手机可扫码 39 | 40 | ![](http://7xqch8.com1.z0.glb.clouddn.com/QQ20170222-193213.png) 41 | 42 | ## 项目总结(未完) 43 | 44 | [暂无](http://yatessss.github.io/2016/07/08/%E4%BD%BF%E7%94%A8vue%E5%AE%8C%E6%88%90%E7%9F%A5%E4%B9%8E%E6%97%A5%E6%8A%A5web%E7%89%88.html) 45 | 46 | ## Dependencies 47 | 48 | ```js 49 | "dependencies": { 50 | "axios": "^0.15.2", 51 | "babel-core": "^6.18.2", 52 | "lib-flexible": "^0.3.2", 53 | "react": "^15.4.0", 54 | "react-dom": "^15.4.0", 55 | "react-redux": "^4.4.6", 56 | "react-router": "^3.0.0", 57 | "redux": "^3.6.0", 58 | "redux-devtools": "^3.3.1", 59 | "redux-devtools-dock-monitor": "^1.1.1", 60 | "redux-devtools-log-monitor": "^1.0.11", 61 | "redux-thunk": "^2.1.0", 62 | "swiper": "^3.4.1", 63 | "webpack-dev-server": "^1.16.2" 64 | } 65 | ``` 66 | 67 | ## Build Setup 68 | 69 | ``` bash 70 | # install dependencies 71 | npm install 72 | 73 | # serve with hot reload at localhost:8080 74 | npm run dev 75 | 76 | # build for production with minification 77 | npm run build 78 | 79 | ``` 80 | 81 | 82 | ## License 83 | 84 | MIT license. 85 | 86 | 感谢 [ZhihuDailyPurify](https://github.com/izzyleung/ZhihuDailyPurify/wiki/%E7%9F%A5%E4%B9%8E%E6%97%A5%E6%8A%A5-API-%E5%88%86%E6%9E%90)整理了API 87 | 88 | -------------------------------------------------------------------------------- /app/DevTools.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/9. 3 | */ 4 | import React from 'react'; 5 | import { createDevTools } from 'redux-devtools'; 6 | import LogMonitor from 'redux-devtools-log-monitor'; 7 | import DockMonitor from 'redux-devtools-dock-monitor'; 8 | 9 | export default createDevTools( 10 | 12 | 13 | 14 | ); 15 | -------------------------------------------------------------------------------- /app/api/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/9. 3 | */ 4 | // const env = { 5 | // THEMES: 'http://news-at.zhihu.com/api/4/themes', 6 | // LATEST_NEWS: 'http://news-at.zhihu.com/api/4/news/latest', 7 | // NEXT_NEWS: 'http://news.at.zhihu.com/api/4/news/before/', 8 | // NEWS_INFO: 'http://news-at.zhihu.com/api/4/news/', 9 | // STORY_EXTRA: 'http://news-at.zhihu.com/api/4/story-extra/', 10 | // GET_THEME: 'http://news-at.zhihu.com/api/4/theme/', 11 | // GET_COMMENTS: 'http://news-at.zhihu.com/api/4/story/', 12 | // GET_SECTION: 'http://news-at.zhihu.com/api/3/section/' 13 | // } 14 | const env = { 15 | THEMES: 'http://api.yatessss.com:8888/news-at/api/4/themes', 16 | LATEST_NEWS: 'http://api.yatessss.com:8888/news-at/api/4/news/latest', 17 | NEXT_NEWS: 'http://api.yatessss.com:8888/news-at/api/4/news/before/', 18 | NEWS_INFO: 'http://api.yatessss.com:8888/news-at/api/4/news/', 19 | STORY_EXTRA: 'http://api.yatessss.com:8888/news-at/api/4/story-extra/', 20 | GET_THEME: 'http://api.yatessss.com:8888/news-at/api/4/theme/', 21 | GET_COMMENTS: 'http://api.yatessss.com:8888/news-at/api/4/story/', 22 | GET_SECTION: 'http://api.yatessss.com:8888/news-at/api/3/section/' 23 | } 24 | console.log(process.env.NODE_ENV) 25 | 26 | export default env 27 | 28 | -------------------------------------------------------------------------------- /app/components/carousel.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { connect } from 'react-redux'; 3 | var Slider = require('react-slick'); 4 | import '../css/slick.scss' 5 | import '../css/slick-theme.scss' 6 | 7 | const SimpleSlider = React.createClass({ 8 | render: function () { 9 | var settings = { 10 | dots: true, 11 | infinite: true, 12 | speed: 500, 13 | slidesToShow: 1, 14 | slidesToScroll: 1 15 | }; 16 | return ( 17 | 18 |

1

19 |

2

20 |

3

21 |

4

22 |

5

23 |

6

24 |
25 | ); 26 | } 27 | }); 28 | 29 | export default connect()(SimpleSlider) -------------------------------------------------------------------------------- /app/components/comment-item.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import '../css/comments-item.scss' 3 | import filter from '../util/filter' 4 | import { connect } from 'react-redux'; 5 | import { showBox} from '../redux/action' 6 | 7 | const commentsItem = React.createClass({ 8 | componentWillMount () { 9 | }, 10 | goBack () { 11 | window.history.back() 12 | }, 13 | render() { 14 | let item = this.props.item 15 | let {dispatch} = this.props 16 | return ( 17 |
  • {dispatch(showBox())}}> 18 |
    19 | {/**/} 20 |
    21 |
    22 |
    23 |
    24 | {item.author} 25 |
    26 |
    27 | {item.likes} 28 |
    29 |
    30 |
    31 |

    {item.content}

    32 | {(()=>{ 33 | if (item.reply_to) { 34 | return ( 35 |

    36 | //{item.reply_to.author}: 37 | {item.reply_to.content} 38 |

    39 | ) 40 | } 41 | })()} 42 |
    43 |
    44 | {filter.formatTime(item.time, "MM-dd hh:mm")} 45 |
    46 |
    47 |
  • 48 | ) 49 | } 50 | }); 51 | 52 | export default connect()(commentsItem) -------------------------------------------------------------------------------- /app/components/common-header.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | // import axios from 'axios'; 3 | import '../css/common-header.scss' 4 | 5 | const commonHeader = React.createClass({ 6 | componentWillMount () { 7 | }, 8 | goBack () { 9 | window.history.back() 10 | }, 11 | render() { 12 | let { title } = this.props 13 | return ( 14 |
    15 |
    16 |

    {title}

    17 |
    18 | ) 19 | } 20 | }); 21 | 22 | export default commonHeader 23 | -------------------------------------------------------------------------------- /app/components/detail-content.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | // import axios from 'axios'; 3 | import { fetchData, initDetailData } from '../redux/action' 4 | import { connect } from 'react-redux' 5 | import { Link } from 'react-router'; 6 | import '../css/zhihu_news_detail.scss' 7 | import '../css/detail-content.scss' 8 | import api from '../api' 9 | import filter from '../util/filter.js' 10 | 11 | 12 | const detailContent = React.createClass({ 13 | componentWillMount () { 14 | let { dispatch} = this.props 15 | dispatch(fetchData(api.NEWS_INFO + this.props.id)) 16 | }, 17 | toHtml () { 18 | let html = this.props.detailContent.body 19 | html = html.replace(/http\w{0,1}:\/\/p/g, 'https://images.weserv.nl/?url=p') 20 | return { 21 | __html: html 22 | } 23 | }, 24 | componentWillUnmount () { 25 | let {dispatch, detailContent} = this.props 26 | let extra = { 27 | comments: detailContent.comments, 28 | long_comments: detailContent.long_comments, 29 | short_comments: detailContent.short_comments 30 | } 31 | window.sessionStorage.extra = JSON.stringify(extra) 32 | dispatch(initDetailData()) 33 | }, 34 | render() { 35 | let { title, image_source, image, section, body, recommenders, id } = this.props.detailContent 36 | return ( 37 |
    38 |
    39 |
    40 |
    41 |

    {title}

    42 |

    {image_source}

    43 |
    44 | 45 | {/**/} 46 | {(()=>{ 47 | if (recommenders && recommenders.length > 0) { 48 | return ( 49 | 50 |
    51 |

    推荐者

    52 | {recommenders.map((item, index)=> 53 |
    54 | 55 |
    56 | )} 57 |
    58 | 59 | ) 60 | } 61 | })()} 62 | 63 | {(()=>{ 64 | if (body) { 65 | return
    66 | } 67 | {/*else {*/} 68 | {/*return */} 69 | {/*}*/} 70 | })()} 71 | 72 | 73 | {(()=>{ 74 | if (section.name) { 75 | return ( 76 |
    77 | 78 |
    79 | 80 |

    本文来自: {section.name} · 合集

    81 |
    82 |
    83 | 84 |
    85 | ) 86 | } 87 | })()} 88 | 89 | 90 |
    91 |
    92 | ) 93 | } 94 | }); 95 | 96 | const mapStateToProps = (state, ownProps) => ({ 97 | detailContent: state.detail_content 98 | }) 99 | 100 | export default connect( 101 | mapStateToProps, 102 | // mapDispatchToProps 103 | )(detailContent) -------------------------------------------------------------------------------- /app/components/detail-header.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | // import axios from 'axios'; 3 | import { fetchData, showCollection, hideCollection, showShare, hideShare} from '../redux/action' 4 | import { connect } from 'react-redux' 5 | import { Link } from 'react-router'; 6 | import '../css/detail-header.scss' 7 | import api from '../api' 8 | import filter from '../util/filter' 9 | 10 | const detailHeader = React.createClass({ 11 | componentWillMount () { 12 | let { dispatch} = this.props 13 | dispatch(fetchData(api.STORY_EXTRA + this.props.id)) 14 | }, 15 | changeCollection () { 16 | let { dispatch} = this.props 17 | let { collection } = this.props.detail_content 18 | if (collection) { 19 | dispatch(hideCollection()) 20 | } else { 21 | dispatch(showCollection()) 22 | } 23 | }, 24 | changeShare () { 25 | let { dispatch} = this.props 26 | let { show_share } = this.props.detail_content 27 | if (show_share) { 28 | dispatch(hideShare()) 29 | } else { 30 | dispatch(showShare()) 31 | } 32 | }, 33 | goBack () { 34 | window.history.back() 35 | }, 36 | render() { 37 | let { comments, popularity, collection, show_share, id } = this.props.detail_content 38 | return ( 39 |
    40 |
    41 |
    42 |
    43 |
    44 |
    45 | 46 |
    47 | {comments} 48 |
    49 | 50 |
    {filter.toK(popularity)}
    51 |
    52 | {(() => { 53 | if (show_share) { 54 | return ( 55 |
    56 |
    57 |

    分享

    58 |
    59 |

    新浪微博

    60 |

    微信

    61 |

    微信朋友圈

    62 |

    QQ空间

    63 |

    推特

    64 |

    QQ

    65 |

    豆瓣

    66 |
    67 |
    68 |
    69 | ) 70 | } 71 | })()} 72 |
    73 | ) 74 | } 75 | }); 76 | 77 | const mapStateToProps = (state, ownProps) => ({ 78 | detail_content: state.detail_content 79 | }) 80 | 81 | export default connect( 82 | mapStateToProps, 83 | // mapDispatchToProps 84 | )(detailHeader) -------------------------------------------------------------------------------- /app/components/list-default.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/15. 3 | */ 4 | import React from 'react' 5 | import { getContentData, getNextNews } from '../redux/action' 6 | import { connect } from 'react-redux'; 7 | import '../css/list-default.scss' 8 | import api from '../api' 9 | import ListItem from '../components/list-item.jsx' 10 | import filter from '../util/filter' 11 | import Slider from './slider.jsx' 12 | 13 | const listDefault = React.createClass({ 14 | componentDidMount () { 15 | let { dispatch } = this.props 16 | dispatch(getContentData(api.LATEST_NEWS)) 17 | window.addEventListener('scroll', this.getScrollList, false) 18 | }, 19 | componentWillUnmount() { 20 | window.removeEventListener('scroll', this.getScrollList, false) 21 | }, 22 | getScrollList () { 23 | let { dispatch } = this.props 24 | if ((window.document.body.offsetHeight + window.document.body.scrollTop) + 100 > window.document.body.scrollHeight && !this.props.loading) { 25 | dispatch(getNextNews(api.NEXT_NEWS + this.props.date)) 26 | } 27 | }, 28 | render() { 29 | let { dispatch, all_stories} = this.props 30 | return ( 31 | 32 |
    33 | {/*// */} 34 | 35 | {/*// */} 36 | {all_stories.map((item, index) => 37 |
    38 | 45 |
    46 | )} 47 |
    48 | ) 49 | } 50 | }); 51 | 52 | const mapStateToProps = (state, ownProps) => ({ 53 | all_stories: state.content_list.all_stories, 54 | date: state.content_list.date, 55 | top_stories: state.content_list.top_stories, 56 | loading: state.content_list.loading, 57 | }) 58 | 59 | export default connect( 60 | mapStateToProps, 61 | // mapDispatchToProps 62 | )(listDefault) 63 | -------------------------------------------------------------------------------- /app/components/list-header.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | // import axios from 'axios'; 3 | import { toggleSidebar, changeMode } from '../redux/action' 4 | import { connect } from 'react-redux'; 5 | import '../css/list-header.scss' 6 | 7 | const listHeader = React.createClass({ 8 | changeMode () { 9 | let {dispatch, night_style} = this.props 10 | dispatch(changeMode()) 11 | console.log(night_style) 12 | if (night_style) { 13 | window.document.getElementById('app').className = '' 14 | } else { 15 | window.document.getElementById('app').className = 'night-style' 16 | } 17 | }, 18 | render() { 19 | let { dispatch, title, iconDisplay } = this.props 20 | return ( 21 |
    22 |
    {dispatch(toggleSidebar())}} >
    23 |

    {title}

    24 | {/*

    tip

    */} 25 | 26 | {(()=>{ 27 | if (iconDisplay) { 28 | return ( 29 |
    30 |
    31 |
    32 |
    33 | ) 34 | } 35 | })()} 36 |
    37 | ) 38 | } 39 | }); 40 | 41 | const mapStateToProps = (state, ownProps) => ({ 42 | night_style: state.content_list.night_style, 43 | list: state.sidebar.list, 44 | active: state.sidebar.active 45 | }) 46 | 47 | export default connect( 48 | mapStateToProps, 49 | // mapDispatchToProps 50 | )(listHeader) 51 | -------------------------------------------------------------------------------- /app/components/list-item.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/15. 3 | */ 4 | import React from 'react' 5 | import { Link } from 'react-router'; 6 | import { connect } from 'react-redux'; 7 | import '../css/list-item.scss' 8 | import filter from '../util/filter.js' 9 | 10 | 11 | const ListItem = React.createClass({ 12 | componentWillMount () { 13 | }, 14 | render() { 15 | let { dispatch } = this.props 16 | let item = this.props.item 17 | return ( 18 | 19 |
    20 |
  • 21 |
    22 |

    {item.title}

    23 | {(()=>{ 24 | if (item.display_date) { 25 | return

    {item.display_date}

    26 | } 27 | })()} 28 |
    29 | {(()=>{ 30 | if (item.images) { 31 | return ( 32 |
    33 | 34 | {(()=>{ 35 | if (item.multipic) { 36 | return

    37 | 38 | 多图 39 |

    40 | } 41 | })()} 42 |
    43 | ) 44 | } 45 | })()} 46 |
  • 47 |
    48 | 49 | ) 50 | } 51 | }); 52 | 53 | // const mapStateToProps = (state, ownProps) => ({ 54 | // list: state.sidebar.list, 55 | // active: state.sidebar.active 56 | // }) 57 | 58 | export default connect()(ListItem) 59 | -------------------------------------------------------------------------------- /app/components/list-theme.jsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/15. 3 | */ 4 | import React from 'react' 5 | import { getThemeData, getThemeBeforeData } from '../redux/action' 6 | import { connect } from 'react-redux'; 7 | import { Link } from 'react-router'; 8 | import '../css/list-theme.scss' 9 | import api from '../api' 10 | import ListItem from '../components/list-item.jsx' 11 | import filter from '../util/filter' 12 | 13 | const listDefault = React.createClass({ 14 | componentDidMount () { 15 | let { dispatch } = this.props 16 | let themeId = this.props.params.id 17 | dispatch(getThemeData(api.GET_THEME + themeId)) 18 | window.addEventListener('scroll', this.getScrollTheme, false) 19 | }, 20 | componentWillUnmount() { 21 | window.removeEventListener('scroll', this.getScrollTheme, false) 22 | }, 23 | // 路由数据更新的时候钩子 24 | componentDidUpdate (prevProps) { 25 | let { dispatch } = this.props 26 | let oldThemeId = prevProps.params.id 27 | let newThemeId = this.props.params.id 28 | if (oldThemeId !== newThemeId) { 29 | dispatch(getThemeData(api.GET_THEME + newThemeId)) 30 | 31 | } 32 | window.sessionStorage.editors = JSON.stringify(this.props.theme_stories.editors) 33 | }, 34 | getScrollTheme () { 35 | let { dispatch, theme_stories } = this.props 36 | let themeId = this.props.params.id 37 | let lastStoriesId = theme_stories.stories[theme_stories.stories.length - 1].id 38 | if ((window.document.body.offsetHeight + window.document.body.scrollTop) + 100 > window.document.body.scrollHeight && !this.props.loading) { 39 | dispatch(getThemeBeforeData(api.GET_THEME + themeId + '/before/' + lastStoriesId)) 40 | } 41 | }, 42 | render() { 43 | let { dispatch, theme_stories} = this.props 44 | let themeId = this.props.params.id 45 | return ( 46 |
    47 |
    48 |
    49 |

    {theme_stories.description}

    50 |

    {theme_stories.imageSource}

    51 |
    52 | {/**/} 53 | {(()=>{ 54 | if (theme_stories.editors && theme_stories.editors.length > 0) { 55 | return ( 56 | 57 |
    58 |

    主编

    59 | {theme_stories.editors.map(item => 60 |
    61 | 62 |
    63 | ) 64 | } 65 |
    66 | 67 | ) 68 | } 69 | })()} 70 | {/**/} 71 |
    72 | 77 |
    78 |
    79 | ) 80 | } 81 | }); 82 | 83 | const mapStateToProps = (state, ownProps) => ({ 84 | theme_stories: state.content_list.theme_stories 85 | }) 86 | 87 | export default connect( 88 | mapStateToProps, 89 | // mapDispatchToProps 90 | )(listDefault) 91 | -------------------------------------------------------------------------------- /app/components/sidebar.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import '../css/sidebar.scss' 3 | import { getSidebarData, toggleSidebar } from '../redux/action' 4 | import { connect } from 'react-redux'; 5 | import api from '../api' 6 | import { Router, Route, Link } from 'react-router' 7 | 8 | const sidebar = React.createClass({ 9 | componentDidMount () { 10 | let { dispatch } = this.props 11 | dispatch(getSidebarData(api.THEMES)) 12 | }, 13 | toggleSidebar () { 14 | let { dispatch } = this.props 15 | dispatch(toggleSidebar()) 16 | }, 17 | render() { 18 | let { dispatch, list, id } = this.props 19 | return ( 20 |
    21 |
    22 | {/**/} 23 | 24 |
    25 |
    26 | 27 |

    yatessss

    28 |
    29 |
    30 |
    31 | 32 |

    我的收藏

    33 |
    34 |
    35 | 36 |

    离线下载

    37 |
    38 |
    39 |
    40 | 41 | {/**/} 42 |
    43 | 44 |

    首页

    45 | 46 |
      47 | 48 | {list.map(item => 49 | 50 |
    • 51 |

      {item.name}

      52 |
      +
      53 |
    • 54 | 55 | )} 56 |
    57 |
    58 |
    59 |
    60 |
    61 | ) 62 | } 63 | }); 64 | 65 | 66 | const mapStateToProps = (state, ownProps) => ({ 67 | list: state.sidebar.list, 68 | active: state.sidebar.active 69 | }) 70 | 71 | // const mapDispatchToProps = (dispatch, ownProps) => ({ 72 | // 73 | // }) 74 | 75 | export default connect( 76 | mapStateToProps, 77 | // mapDispatchToProps 78 | )(sidebar) 79 | 80 | -------------------------------------------------------------------------------- /app/components/slider.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { connect } from 'react-redux'; 3 | import { Link } from 'react-router'; 4 | import filter from '../util/filter' 5 | import '../css/slider.scss' 6 | import Swiper from 'swiper' 7 | window.Swiper = Swiper 8 | 9 | const SimpleSlider = React.createClass({ 10 | componentDidMount () { 11 | new window.Swiper('.swiper-container', { 12 | pagination: '.swiper-pagination', 13 | paginationClickable: true, 14 | spaceBetween: 0, 15 | centeredSlides: true, 16 | autoplay: 4000, 17 | autoplayDisableOnInteraction: false, 18 | observer: true, 19 | lazyLoading: true, 20 | resistanceRatio: 0 21 | }) 22 | }, 23 | render: function () { 24 | let {slider} = this.props 25 | return ( 26 |
    27 |
    28 |
    29 | {/*
    */} 30 | {slider.map(item=> 31 |
    32 | 33 |
    34 |

    {item.title}

    35 | 36 |
    37 | )} 38 |
    39 | {/**/} 40 |
    41 |
    42 |
    43 | ); 44 | } 45 | }); 46 | 47 | export default connect((state)=> { 48 | return { 49 | slider: state.content_list.top_stories 50 | }; 51 | })(SimpleSlider) -------------------------------------------------------------------------------- /app/css/author.scss: -------------------------------------------------------------------------------- 1 | .author-wrap { 2 | margin-top: 50px; 3 | .photo{ 4 | width: 80px; 5 | height: auto; 6 | margin: 0 auto; 7 | padding: 30px 0; 8 | img{ 9 | width: 80px; 10 | height: 80px; 11 | border-radius: 50%; 12 | } 13 | } 14 | .name{ 15 | width: 100px; 16 | margin: 0 auto 30px auto; 17 | padding-bottom: 2px; 18 | color: #999; 19 | font-size: 20px; 20 | text-align: center; 21 | border-bottom: 1px solid #4bb6ae; 22 | } 23 | ul{ 24 | width: 150px; 25 | margin: 0 auto; 26 | font-size: 18px; 27 | text-align: center; 28 | border-top: 1px solid #b6b6b6; 29 | li{ 30 | padding: 10px; 31 | border-bottom: 1px solid #b6b6b6; 32 | p{ 33 | color: #999; 34 | } 35 | a{ 36 | color: #2482ab; 37 | } 38 | } 39 | } 40 | .btn{ 41 | margin: 50px auto 0 auto; 42 | width: 100px; 43 | height: 40px; 44 | border: 1px solid #999; 45 | border-radius: 10px; 46 | color: #b22323; 47 | font-size: 18px; 48 | text-align: center; 49 | line-height: 40px; 50 | } 51 | } -------------------------------------------------------------------------------- /app/css/comments-item.scss: -------------------------------------------------------------------------------- 1 | 2 | .comment-li{ 3 | border-top: 1px solid #c3c3c3; 4 | padding: 10px 15px 10px 55px; 5 | position: relative; 6 | .iconfont { 7 | font-family:"iconfont"; 8 | font-size: 12px; 9 | font-style:normal; 10 | color: #b0b0b0; 11 | } 12 | .img-box{ 13 | position: absolute; 14 | top: 12px; 15 | left: 15px; 16 | img{ 17 | height: 30px; 18 | width: 30px; 19 | border-radius: 50%; 20 | } 21 | } 22 | .comment-content{ 23 | display: flex; 24 | flex-direction: column; 25 | .content-header{ 26 | margin-bottom: 5px; 27 | display: flex; 28 | flex-direction: row; 29 | .author{ 30 | flex: 1; 31 | font-size: 15px; 32 | font-weight: bold; 33 | } 34 | .likes{ 35 | color: #b0b0b0; 36 | font-size: 12px; 37 | } 38 | } 39 | .content-main{ 40 | padding-right: 15px; 41 | font-size: 14px; 42 | margin-bottom: 10px; 43 | .reply{ 44 | font-size: 15px; 45 | font-weight: bold; 46 | >span{ 47 | font-weight: normal; 48 | font-size: 14px; 49 | color: #8c8c8c; 50 | } 51 | } 52 | } 53 | .content-time{ 54 | color: #b0b0b0; 55 | font-size: 13px; 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /app/css/comments.scss: -------------------------------------------------------------------------------- 1 | .comments-header{ 2 | position: fixed; 3 | transform: translateZ(0); 4 | top: 0; 5 | z-index: 4; 6 | height: 50px; 7 | width: 100%; 8 | background: #00A2EA; 9 | display: flex; 10 | flex-direction: row; 11 | .header-icon{ 12 | flex:1; 13 | text-align: center; 14 | >i{ 15 | line-height: 53px; 16 | } 17 | >span{ 18 | color: #ffffff; 19 | font-size: 14px; 20 | margin-left: 3px; 21 | } 22 | .collection{ 23 | color: #FFCE00; 24 | } 25 | } 26 | .header-cont { 27 | flex: 6; 28 | padding-left: 10px; 29 | >p{ 30 | line-height: 50px; 31 | color: #ffffff; 32 | font-size:16px; 33 | span{ 34 | font-size: 18px; 35 | } 36 | } 37 | } 38 | } 39 | .long-comments{ 40 | margin-top: 50px; 41 | .long-comments-nav{ 42 | padding: 10px 10px 10px 15px; 43 | font-size: 13px; 44 | span{ 45 | font-size: 15px; 46 | } 47 | } 48 | .no-comments{ 49 | border-top: 1px solid #c3c3c3; 50 | height: 530px; 51 | .no-comments-icon{ 52 | width: 150px; 53 | height: 170px; 54 | position: absolute; 55 | top: 50%; 56 | left: 50%; 57 | transform: translate(-50%, -50%); 58 | color: #b0b0b0; 59 | text-align: center; 60 | >i{ 61 | font-size: 85px; 62 | color: #b0b0b0; 63 | } 64 | >p{ 65 | font-size: 15px; 66 | } 67 | } 68 | } 69 | } 70 | .short-comments-nav{ 71 | border-top: 1px solid #c3c3c3; 72 | padding: 10px 10px 10px 15px; 73 | font-size: 13px; 74 | position: relative; 75 | span{ 76 | font-size: 15px; 77 | } 78 | .down{ 79 | position: absolute; 80 | font-size: 15px; 81 | top: 10px; 82 | right: 15px; 83 | color: #b0b0b0; 84 | } 85 | } 86 | 87 | .mask{ 88 | position: fixed; 89 | transform: translateZ(0); 90 | top: 0; 91 | left: 0; 92 | width: 375px; 93 | height: 667px; 94 | background: rgba(0,0,0,0.7); 95 | z-index: 5; 96 | .reply-box{ 97 | width: 320px; 98 | border-radius: 3px; 99 | padding: 5px 20px; 100 | position: absolute; 101 | left: 50%; 102 | top: 50%; 103 | transform: translate(-50%, -50%); 104 | background: #f2f2f2; 105 | >p{ 106 | font-size: 15px; 107 | padding: 5px 0; 108 | } 109 | } 110 | } -------------------------------------------------------------------------------- /app/css/common-header.scss: -------------------------------------------------------------------------------- 1 | 2 | .common-header{ 3 | position: fixed; 4 | transform: translateZ(0); 5 | top: 0; 6 | z-index: 4; 7 | height: 50px; 8 | width: 100%; 9 | background: #00A2EA; 10 | display: flex; 11 | flex-direction: row; 12 | .iconfont { 13 | font-family:"iconfont"; 14 | font-size: 19px; 15 | font-style:normal; 16 | color: #ffffff; 17 | margin-right: 3px; 18 | } 19 | .header-icon{ 20 | flex:1; 21 | text-align: center; 22 | >i{ 23 | line-height: 53px; 24 | } 25 | >span{ 26 | color: #ffffff; 27 | font-size: 14px; 28 | margin-left: 3px; 29 | } 30 | .collection{ 31 | color: #FFCE00; 32 | } 33 | } 34 | .header-cont { 35 | flex: 6; 36 | padding-left: 10px; 37 | >p{ 38 | line-height: 50px; 39 | color: #ffffff; 40 | font-size:16px; 41 | span{ 42 | font-size: 18px; 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /app/css/detail-content.scss: -------------------------------------------------------------------------------- 1 | 2 | .iconfont { 3 | font-family:"iconfont"; 4 | font-size: 30px; 5 | font-style: normal; 6 | font-weight: 100; 7 | color: #ffffff; 8 | } 9 | .color-red{ 10 | background: #ED4016; 11 | } 12 | .color-blue-1{ 13 | background: #2EA2EB; 14 | } 15 | .color-blue-2{ 16 | background: #2269C5; 17 | } 18 | .color-green-1{ 19 | background: #5FC74A; 20 | } 21 | .color-green-2{ 22 | background: #71CE25; 23 | } 24 | .color-green-3{ 25 | background: #228A31; 26 | } 27 | .color-yellow{ 28 | background: #FFCE00; 29 | } 30 | 31 | .detail-main-box{ 32 | padding-top: 50px; 33 | } 34 | 35 | iframe{ 36 | width: 100%; 37 | height: 600px; 38 | } 39 | .mask{ 40 | position: fixed; 41 | transform: translateZ(0); 42 | top: 0; 43 | left: 0; 44 | width: 375px; 45 | height: 667px; 46 | background: rgba(0,0,0,0.7); 47 | z-index: 5; 48 | .share-box{ 49 | width: 330px; 50 | height: 330px; 51 | border-radius: 3px; 52 | padding: 20px; 53 | position: absolute; 54 | left: 50%; 55 | top: 50%; 56 | transform: translate(-50%, -50%); 57 | background: #f2f2f2; 58 | .share-title{ 59 | font-size: 18px; 60 | } 61 | .share-content{ 62 | height: 260px; 63 | width: 290px; 64 | display: flex; 65 | flex-wrap: wrap; 66 | .child{ 67 | flex: 0 0 33.33%; 68 | .icon{ 69 | width: 50px; 70 | height: 50px; 71 | margin: 5px auto; 72 | border-radius: 50%; 73 | position: relative; 74 | text-align: center; 75 | i{ 76 | line-height: 50px; 77 | } 78 | } 79 | >p{ 80 | color: #242424; 81 | text-align: center; 82 | font-size: 13px; 83 | } 84 | } 85 | } 86 | } 87 | } 88 | .detail-img-box{ 89 | position: relative; 90 | z-index: 0; 91 | height: 200px; 92 | width: 100%; 93 | background-size: 100%; 94 | background-position: center; 95 | background-repeat: no-repeat; 96 | .detail-mask{ 97 | width: 100%; 98 | height: 100%; 99 | position: absolute; 100 | top: 0; 101 | left: 0; 102 | background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.1) 40%, rgba(0,0,0,0.1) 100%); 103 | background-image: linear-gradient(bottom, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.1) 40%, rgba(0,0,0,0.1) 100%); 104 | } 105 | .detail-title{ 106 | position: absolute; 107 | bottom: 23px; 108 | line-height: 1.2; 109 | left: 0; 110 | padding: 0 18px; 111 | font-weight: 300; 112 | font-size: 21px; 113 | color: #ffffff; 114 | } 115 | .detail-image-source{ 116 | position: absolute; 117 | bottom: 8px; 118 | right: 0; 119 | padding: 0 18px; 120 | font-weight: 300; 121 | font-size: 12px; 122 | color: #d3d3d3; 123 | } 124 | } 125 | .section-box{ 126 | padding: 0 20px 25px 20px; 127 | width: 375px; 128 | a { 129 | color: #2c3e50; 130 | } 131 | .section-btn{ 132 | background: #f0f0f0; 133 | width: 335px; 134 | height: 50px; 135 | position: relative; 136 | display: flex; 137 | flex-direction: row; 138 | >img{ 139 | width: 50px; 140 | height: 50px; 141 | } 142 | >p{ 143 | flex: 1; 144 | line-height: 50px; 145 | margin-left: 10px; 146 | font-size: 13px; 147 | } 148 | .arrow{ 149 | display: block; 150 | width: 10px; 151 | height: 10px; 152 | position: absolute; 153 | top: 20px; 154 | right: 15px; 155 | border: solid #867e7a; 156 | border-width: 1px 1px 0 0; 157 | -webkit-transform: rotate(45deg); 158 | transform: rotate(45deg); 159 | } 160 | } 161 | } 162 | 163 | .recommenders-box{ 164 | background: #efefef; 165 | position: relative; 166 | display: flex; 167 | flex-direction: row; 168 | flex-wrap: wrap; 169 | padding-left: 70px; 170 | p{ 171 | color: #2c3e50; 172 | position: absolute; 173 | top: 13px; 174 | left: 20px; 175 | font-size: 13px; 176 | font-weight: bold; 177 | } 178 | .recommenders-item{ 179 | height: 30px; 180 | width: 30px; 181 | margin: 7px; 182 | >img{ 183 | height: 30px; 184 | width: 30px; 185 | border-radius: 50%; 186 | } 187 | } 188 | } -------------------------------------------------------------------------------- /app/css/detail-header.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'iconfont'; /* project id:"114066" */ 3 | src: url('//at.alicdn.com/t/font_1467357626_5109937.eot'); 4 | src: url('//at.alicdn.com/t/font_1467357626_5109937.eot?#iefix') format('embedded-opentype'), 5 | url('//at.alicdn.com/t/font_1467357626_5109937.woff') format('woff'), 6 | url('//at.alicdn.com/t/font_1467357626_5109937.ttf') format('truetype'), 7 | url('//at.alicdn.com/t/font_1467357626_5109937.svg#iconfont') format('svg'); 8 | } 9 | .iconfont { 10 | font-family:"iconfont"; 11 | font-size: 19px; 12 | font-style:normal; 13 | color: #ffffff; 14 | } 15 | .iconfont-1 { 16 | font-family:"iconfont"; 17 | font-size: 30px; 18 | font-style:normal; 19 | color: #ffffff; 20 | } 21 | 22 | .detail-header{ 23 | position: fixed; 24 | transform: translateZ(0); 25 | top: 0; 26 | z-index: 4; 27 | height: 50px; 28 | width: 100%; 29 | background: #00A2EA; 30 | display: flex; 31 | flex-direction: row; 32 | padding-right: 10px; 33 | .header-icon{ 34 | flex:1; 35 | text-align: center; 36 | >i{ 37 | line-height: 53px; 38 | } 39 | >span{ 40 | color: #ffffff; 41 | font-size: 14px; 42 | margin-left: 3px; 43 | } 44 | .collection{ 45 | color: #FFCE00; 46 | } 47 | } 48 | .detail-cont { 49 | flex: 2; 50 | padding-left: 10px; 51 | >p{ 52 | line-height: 50px; 53 | color: #ffffff; 54 | font-size:16px; 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /app/css/editor.scss: -------------------------------------------------------------------------------- 1 | .editor-wrap { 2 | ul{ 3 | padding: 0 15px 15px 15px; 4 | margin-top: 50px; 5 | .title{ 6 | color: #8c8c8c; 7 | margin-bottom: 15px; 8 | } 9 | li{ 10 | padding: 10px 0; 11 | border-bottom: 1px solid #d1d1d1; 12 | a{ 13 | display: flex; 14 | flex-direction: row; 15 | overflow: hidden; 16 | .img-box{ 17 | height: 40px; 18 | width: 40px; 19 | img{ 20 | height: 40px; 21 | width: 40px; 22 | border-radius: 50%; 23 | } 24 | } 25 | .info{ 26 | margin-left: 10px; 27 | .name{ 28 | font-size: 15px; 29 | font-weight: bold; 30 | color: #000; 31 | } 32 | .bio{ 33 | color: #8c8c8c; 34 | font-size: 12px; 35 | white-space: nowrap; 36 | } 37 | } 38 | } 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /app/css/list-default.scss: -------------------------------------------------------------------------------- 1 | .list-box{ 2 | padding: 10px 5px 0 5px; 3 | background: #f2f2f2; 4 | } 5 | .title{ 6 | color: #76787e; 7 | margin-left: 15px; 8 | margin-bottom: 12px; 9 | font-size: 14px; 10 | font-weight: 500; 11 | } 12 | @font-face { 13 | font-family: 'iconfont'; /* project id:"114066" */ 14 | src: url('//at.alicdn.com/t/font_1467357626_5109937.eot'); 15 | src: url('//at.alicdn.com/t/font_1467357626_5109937.eot?#iefix') format('embedded-opentype'), 16 | url('//at.alicdn.com/t/font_1467357626_5109937.woff') format('woff'), 17 | url('//at.alicdn.com/t/font_1467357626_5109937.ttf') format('truetype'), 18 | url('//at.alicdn.com/t/font_1467357626_5109937.svg#iconfont') format('svg'); 19 | } 20 | -------------------------------------------------------------------------------- /app/css/list-header.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'iconfont'; /* project id:"114066" */ 3 | src: url('//at.alicdn.com/t/font_1467357626_5109937.eot'); 4 | src: url('//at.alicdn.com/t/font_1467357626_5109937.eot?#iefix') format('embedded-opentype'), 5 | url('//at.alicdn.com/t/font_1467357626_5109937.woff') format('woff'), 6 | url('//at.alicdn.com/t/font_1467357626_5109937.ttf') format('truetype'), 7 | url('//at.alicdn.com/t/font_1467357626_5109937.svg#iconfont') format('svg'); 8 | } 9 | 10 | .iconfont { 11 | font-family:"iconfont"; 12 | font-size:19px; 13 | font-style:normal; 14 | color: #ffffff; 15 | } 16 | 17 | .list-header{ 18 | position: fixed; 19 | transform: translateZ(0); 20 | top: 0; 21 | z-index: 4; 22 | height: 50px; 23 | width: 100%; 24 | background: #00A2EA; 25 | display: flex; 26 | flex-direction: row; 27 | .header-icon{ 28 | flex:1; 29 | text-align: center; 30 | >i{ 31 | line-height: 53px; 32 | } 33 | } 34 | .header-cont { 35 | flex: 6; 36 | padding-left: 10px; 37 | >p{ 38 | line-height: 50px; 39 | color: #ffffff; 40 | font-size:16px; 41 | } 42 | } 43 | .header-icon-wrap{ 44 | flex: 2; 45 | display: flex; 46 | .header-icon{ 47 | flex:1; 48 | text-align: center; 49 | >i{ 50 | line-height: 53px; 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/css/list-item.scss: -------------------------------------------------------------------------------- 1 | .list-item-wrap { 2 | color: #2c3e50; 3 | .iconfont { 4 | font-family:"iconfont"; 5 | font-size: 10px; 6 | font-style:normal; 7 | color: #ffffff; 8 | margin-right: 3px; 9 | } 10 | .list-detail-box{ 11 | position: relative; 12 | min-height: 63px; 13 | width: 97%; 14 | margin: 8px auto 0 auto; 15 | background: #ffffff; 16 | padding: 13px; 17 | display: flex; 18 | flex-direction: row; 19 | border-radius: 5px; 20 | border: 1px solid #eaeaea; 21 | border-bottom: 1px solid #d0d0d0; 22 | .list-content-box{ 23 | margin-right: 10px; 24 | flex: 1; 25 | >p{ 26 | font-size: 17px; 27 | line-height: 1.2; 28 | } 29 | .time{ 30 | position: absolute; 31 | bottom: 10px; 32 | left: 13px; 33 | font-size: 13px; 34 | color: #b0b0b0; 35 | } 36 | } 37 | .list-img-box{ 38 | position: relative; 39 | width: 75px; 40 | height: 70px; 41 | >img{ 42 | width: 75px; 43 | height: 70px; 44 | } 45 | .tip{ 46 | color: #ffffff; 47 | position: absolute; 48 | bottom: 0; 49 | right: 0; 50 | font-size: 10px; 51 | padding: 2px 4px; 52 | background: rgba(0, 0, 0, 0.5); 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/css/list-theme.scss: -------------------------------------------------------------------------------- 1 | .theme-list { 2 | .margin-top{ 3 | margin-top: 50px; 4 | } 5 | .detail-img-box{ 6 | position: relative; 7 | z-index: 0; 8 | height: 230px; 9 | width: 100%; 10 | background-size: 100%; 11 | background-position: center; 12 | background-repeat: no-repeat; 13 | .detail-mask{ 14 | width: 100%; 15 | height: 100%; 16 | position: absolute; 17 | top: 0; 18 | left: 0; 19 | background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.1) 40%, rgba(0,0,0,0.1) 100%); 20 | background-image: linear-gradient(bottom, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.1) 40%, rgba(0,0,0,0.1) 100%); 21 | } 22 | .detail-title{ 23 | position: absolute; 24 | bottom: 23px; 25 | line-height: 1.2; 26 | left: 0; 27 | padding: 0 18px; 28 | font-weight: 300; 29 | font-size: 21px; 30 | color: #ffffff; 31 | } 32 | .detail-image-source{ 33 | position: absolute; 34 | bottom: 8px; 35 | right: 0; 36 | padding: 0 18px; 37 | font-weight: 300; 38 | font-size: 12px; 39 | color: #d3d3d3; 40 | } 41 | } 42 | .list-box{ 43 | padding: 1px 5px 0 5px; 44 | background: #f2f2f2; 45 | } 46 | .editors-box{ 47 | background: #efefef; 48 | position: relative; 49 | display: flex; 50 | flex-direction: row; 51 | flex-wrap: wrap; 52 | padding-left: 50px; 53 | p{ 54 | position: absolute; 55 | top: 13px; 56 | left: 15px; 57 | font-size: 13px; 58 | font-weight: bold; 59 | color: #2c3e50; 60 | } 61 | .editors-item{ 62 | height: 30px; 63 | width: 30px; 64 | margin: 7px 7px 0 7px; 65 | >img{ 66 | height: 30px; 67 | width: 30px; 68 | border-radius: 50%; 69 | } 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /app/css/main.scss: -------------------------------------------------------------------------------- 1 | @import "./reset"; 2 | @font-face { 3 | font-family: 'iconfont'; 4 | src: url('//at.alicdn.com/t/font_1467357626_5109937.eot'); /* IE9*/ 5 | src: url('//at.alicdn.com/t/font_1467357626_5109937.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 6 | url('//at.alicdn.com/t/font_1467357626_5109937.woff') format('woff'), /* chrome、firefox */ 7 | url('//at.alicdn.com/t/font_1467357626_5109937.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ 8 | url('//at.alicdn.com/t/font_1467357626_5109937.svg#iconfont') format('svg'); /* iOS 4.1- */ 9 | } 10 | html, 11 | body { 12 | border: 0; 13 | font-family: "Helvetica-Neue", "Helvetica", Arial, sans-serif; 14 | line-height: 1.5; 15 | margin: 0; 16 | padding: 0; 17 | } 18 | 19 | div, 20 | span, 21 | object, 22 | iframe, 23 | img, 24 | table, 25 | caption, 26 | thead, 27 | tbody, 28 | tfoot, 29 | tr, 30 | tr, 31 | td, 32 | article, 33 | aside, 34 | canvas, 35 | details, 36 | figure, 37 | hgroup, 38 | menu, 39 | nav, 40 | footer, 41 | header, 42 | section, 43 | summary, 44 | mark, 45 | audio, 46 | video { 47 | border: 0; 48 | margin: 0; 49 | padding: 0; 50 | } 51 | 52 | h1, 53 | h2, 54 | h3, 55 | h4, 56 | h5, 57 | h6, 58 | p, 59 | blockquote, 60 | pre, 61 | a, 62 | abbr, 63 | address, 64 | cit, 65 | code, 66 | del, 67 | dfn, 68 | em, 69 | ins, 70 | q, 71 | samp, 72 | small, 73 | strong, 74 | sub, 75 | sup, 76 | b, 77 | i, 78 | hr, 79 | dl, 80 | dt, 81 | dd, 82 | ol, 83 | ul, 84 | li, 85 | fieldset, 86 | legend, 87 | label { 88 | border: 0; 89 | font-size: 100%; 90 | vertical-align: baseline; 91 | margin: 0; 92 | padding: 0; 93 | } 94 | 95 | article, 96 | aside, 97 | canvas, 98 | figure, 99 | figure img, 100 | figcaption, 101 | hgroup, 102 | footer, 103 | header, 104 | nav, 105 | section, 106 | audio, 107 | video { 108 | display: block; 109 | } 110 | 111 | table { 112 | border-collapse: separate; 113 | border-spacing: 0; 114 | } 115 | 116 | table caption, 117 | table th, 118 | table td { 119 | text-align: left; 120 | vertical-align: middle; 121 | } 122 | 123 | li { 124 | list-style: none; 125 | } 126 | 127 | a { 128 | text-decoration: none; 129 | } 130 | 131 | a img { 132 | border: 0; 133 | } 134 | 135 | :focus { 136 | outline: 0; 137 | } 138 | 139 | * { 140 | -webkit-box-sizing: border-box; 141 | } 142 | 143 | textarea { 144 | resize: none; 145 | -webkit-appearance: none; 146 | } 147 | 148 | input { 149 | -webkit-appearance: none; 150 | } 151 | 152 | select { 153 | -webkit-appearance: none; 154 | background-color: #fff; 155 | } 156 | 157 | @font-face { 158 | font-family: 'iconfont'; 159 | src: url("//at.alicdn.com/t/font_1467357626_5109937.eot"); 160 | /* IE9*/ 161 | src: url("//at.alicdn.com/t/font_1467357626_5109937.eot?#iefix") format("embedded-opentype"), url("//at.alicdn.com/t/font_1467357626_5109937.woff") format("woff"), url("//at.alicdn.com/t/font_1467357626_5109937.ttf") format("truetype"), url("//at.alicdn.com/t/font_1467357626_5109937.svg#iconfont") format("svg"); 162 | /* iOS 4.1- */ 163 | } 164 | .iconfont { 165 | font-family:"iconfont"; 166 | font-size:19px; 167 | font-style:normal; 168 | color: #ffffff; 169 | } 170 | .scroll-stop{ 171 | overflow: hidden; 172 | } 173 | 174 | .main-list{ 175 | margin-top: 50px; 176 | } 177 | 178 | .sidebar-mask{ 179 | /*width: 357px;*/ 180 | /*height: 667px;*/ 181 | position: fixed; 182 | transform: translateZ(0); 183 | top: 0; 184 | right: 0; 185 | bottom: 0; 186 | left: 0; 187 | z-index: 5; 188 | background: rgba(0, 0, 0, 0.7); 189 | } 190 | .list{ 191 | background: #efefef; 192 | } 193 | 194 | html { 195 | height: 100%; 196 | /*overflow: auto;*/ 197 | } 198 | 199 | body { 200 | display: flex; 201 | align-items: center; 202 | justify-content: center; 203 | height: 100%; 204 | } 205 | 206 | #app { 207 | color: #2c3e50; 208 | height: 100%; 209 | width: 100%; 210 | font-family: Source Sans Pro, Helvetica, sans-serif; 211 | } 212 | 213 | #app.night-style{ 214 | background: #343434; 215 | .list-header{ 216 | background: #222222; 217 | } 218 | .detail-header{ 219 | background: #222222; 220 | } 221 | .list-box{ 222 | background: #343434; 223 | .title{ 224 | color: #B7B7B7; 225 | } 226 | .list-detail-box{ 227 | background: #404040; 228 | border: 1px solid #343434; 229 | border-bottom: 1px solid #222222; 230 | .list-content-box{ 231 | color: #d2d2d2; 232 | } 233 | } 234 | } 235 | .section-list{ 236 | background: #343434; 237 | .title{ 238 | color: #B7B7B7; 239 | } 240 | .list-detail-box{ 241 | background: #404040; 242 | border: 1px solid #343434; 243 | border-bottom: 1px solid #222222; 244 | .list-content-box{ 245 | color: #d2d2d2; 246 | } 247 | } 248 | } 249 | .mask{ 250 | .share-box{ 251 | background: #343434; 252 | p{ 253 | color: #B7B7B7; 254 | } 255 | } 256 | } 257 | .sidebar-header{ 258 | background: #222222; 259 | p{ 260 | color: #B7B7B7; 261 | } 262 | } 263 | .sidebar-list{ 264 | background: #343434; 265 | .sidebar-list-first{ 266 | background: #343434; 267 | } 268 | .sidebar-list-ul p{ 269 | color: #B7B7B7; 270 | } 271 | } 272 | .editors-box{ 273 | background: #343434; 274 | color: #B7B7B7; 275 | p { 276 | color: #B7B7B7; 277 | } 278 | } 279 | .name{ 280 | color: #B7B7B7; 281 | } 282 | .content-wrap{ 283 | background: #343434; 284 | .headline { 285 | border-bottom: #303030; 286 | } 287 | .headline-title{ 288 | color: #B7B7B7; 289 | } 290 | .content-inner{ 291 | background: #343434; 292 | .question + .question{ 293 | border-top: 4px solid #222222; 294 | } 295 | .answer { 296 | border: #303030; 297 | } 298 | } 299 | .heading-content{ 300 | color: #888888; 301 | } 302 | .question-title{ 303 | color: #B7B7B7; 304 | } 305 | .content{ 306 | color: #888888; 307 | } 308 | .author{ 309 | color: #888888; 310 | } 311 | .view-more{ 312 | a{ 313 | background: #303030; 314 | color: #6991C2; 315 | } 316 | } 317 | } 318 | .section-box{ 319 | background: #343434; 320 | .section-btn{ 321 | background: #303030; 322 | p{ 323 | color: #888888; 324 | } 325 | } 326 | } 327 | .recommenders-box{ 328 | background: #343434; 329 | color: #B7B7B7; 330 | p { 331 | color: #B7B7B7; 332 | } 333 | } 334 | .comments-header{ 335 | background: #222222; 336 | } 337 | .long-comments{ 338 | background: #343434; 339 | .long-comments-nav{ 340 | color: #B7B7B7; 341 | } 342 | .comment-content{ 343 | color: #888888; 344 | } 345 | } 346 | .short-comments{ 347 | background: #343434; 348 | .short-comments-nav{ 349 | color: #B7B7B7; 350 | } 351 | .comment-content{ 352 | color: #888888; 353 | } 354 | } 355 | .no-comments{ 356 | border-top: 1px solid #888888; 357 | } 358 | .common-header{ 359 | background: #222222; 360 | } 361 | .list{ 362 | background: #343434; 363 | .list-detail-box{ 364 | background: #404040; 365 | border: 1px solid #343434; 366 | border-bottom: 1px solid #222222; 367 | .list-content-box{ 368 | color: #d2d2d2; 369 | } 370 | } 371 | } 372 | } 373 | -------------------------------------------------------------------------------- /app/css/recommender.scss: -------------------------------------------------------------------------------- 1 | .recommender-wrap { 2 | 3 | ul{ 4 | padding: 15px; 5 | margin-top: 50px; 6 | .title{ 7 | color: #8c8c8c; 8 | margin-bottom: 15px; 9 | font-size: 13px; 10 | margin-left: 0; 11 | } 12 | li{ 13 | padding: 10px 0; 14 | border-top: 1px solid #d1d1d1; 15 | a{ 16 | display: flex; 17 | flex-direction: row; 18 | overflow: hidden; 19 | .img-box{ 20 | height: 40px; 21 | width: 40px; 22 | img{ 23 | height: 40px; 24 | width: 40px; 25 | border-radius: 50%; 26 | } 27 | } 28 | .info{ 29 | margin-left: 10px; 30 | .name{ 31 | font-size: 15px; 32 | font-weight: bold; 33 | color: #000; 34 | .zhubian{ 35 | display: inline-block; 36 | width: 40px; 37 | height: 20px; 38 | background: #4ed1ad; 39 | border-radius: 5px; 40 | color: #ffffff; 41 | font-size: 13px; 42 | line-height: 20px; 43 | text-align: center; 44 | margin-left: 10px; 45 | } 46 | } 47 | .bio{ 48 | color: #8c8c8c; 49 | font-size: 12px; 50 | white-space: nowrap; 51 | } 52 | } 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /app/css/reset.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Global Reset of all HTML Elements 3 | * 4 | * Resetting all of our HTML Elements ensures a smoother 5 | * visual transition between browsers. If you don't believe me, 6 | * try temporarily commenting out this block of code, then go 7 | * and look at Mozilla versus Safari, both good browsers with 8 | * a good implementation of CSS. The thing is, all browser CSS 9 | * defaults are different and at the end of the day if visual 10 | * consistency is what we're shooting for, then we need to 11 | * make sure we're resetting all spacing elements. 12 | * 13 | */ 14 | html, body { 15 | border: 0; 16 | font-family: "Helvetica-Neue", "Helvetica", Arial, sans-serif; 17 | line-height: 1.5; 18 | margin: 0; 19 | padding: 0; 20 | } 21 | 22 | div, span, object, iframe, img, table, caption, thead, tbody, 23 | tfoot, tr, tr, td, article, aside, canvas, details, figure, hgroup, menu, 24 | nav, footer, header, section, summary, mark, audio, video { 25 | border: 0; 26 | margin: 0; 27 | padding: 0; 28 | } 29 | 30 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, address, cit, code, 31 | del, dfn, em, ins, q, samp, small, strong, sub, sup, b, i, hr, dl, dt, dd, 32 | ol, ul, li, fieldset, legend, label { 33 | border: 0; 34 | font-size: 100%; 35 | vertical-align: baseline; 36 | margin: 0; 37 | padding: 0; 38 | } 39 | 40 | article, aside, canvas, figure, figure img, figcaption, hgroup, 41 | footer, header, nav, section, audio, video { 42 | display: block; 43 | } 44 | 45 | table { 46 | border-collapse: separate; 47 | border-spacing: 0; 48 | caption, th, td { 49 | text-align: left; 50 | vertical-align: middle; 51 | } 52 | } 53 | li{ 54 | list-style: none; 55 | } 56 | a{ 57 | text-decoration: none; 58 | } 59 | a img { 60 | border: 0; 61 | color: #000; 62 | } 63 | 64 | :focus { 65 | outline: 0; 66 | } 67 | *{ 68 | -webkit-box-sizing: border-box; 69 | } 70 | textarea{ 71 | resize: none; 72 | -webkit-appearance: none; 73 | } 74 | input{ 75 | -webkit-appearance: none; 76 | } 77 | select { 78 | -webkit-appearance: none; 79 | background-color: #fff; 80 | } 81 | -------------------------------------------------------------------------------- /app/css/section.scss: -------------------------------------------------------------------------------- 1 | .section-wrap { 2 | .section-list{ 3 | margin-top: 50px; 4 | padding: 1px 5px 0 5px; 5 | background: #f2f2f2; 6 | } 7 | } -------------------------------------------------------------------------------- /app/css/sidebar.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'iconfont'; 3 | src: url('//at.alicdn.com/t/font_1467357626_5109937.eot'); /* IE9*/ 4 | src: url('//at.alicdn.com/t/font_1467357626_5109937.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ 5 | url('//at.alicdn.com/t/font_1467357626_5109937.woff') format('woff'), /* chrome、firefox */ 6 | url('//at.alicdn.com/t/font_1467357626_5109937.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/ 7 | url('//at.alicdn.com/t/font_1467357626_5109937.svg#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .show-sidebar{ 11 | transform: translateX(290px); 12 | } 13 | .sidebar-box{ 14 | position: fixed; 15 | transform: translateZ(0); 16 | height: 100%; 17 | overflow: auto; 18 | width: 290px; 19 | left: -290px; 20 | z-index: 99; 21 | top: 0; 22 | bottom: 0; 23 | transition: all .3s ease; 24 | .iconfont { 25 | font-family:"iconfont"; 26 | font-size: 14px; 27 | font-style:normal; 28 | color: #ffffff; 29 | } 30 | &.show-sidebar{ 31 | transform: translateX(290px); 32 | } 33 | .swiper-slide { 34 | font-size: 15px; 35 | height: auto; 36 | -webkit-box-sizing: border-box; 37 | box-sizing: border-box; 38 | } 39 | } 40 | .sidebar-box{ 41 | .sidebar-header{ 42 | padding: 15px; 43 | background: #00A2EA; 44 | .user{ 45 | display: flex; 46 | flex-direction: row; 47 | >img{ 48 | width: 30px; 49 | height: 30px; 50 | border-radius: 50%; 51 | } 52 | >p{ 53 | margin-left: 20px; 54 | line-height: 30px; 55 | flex: 1; 56 | font-size: 18px; 57 | font-weight: 300; 58 | color: #ffffff; 59 | } 60 | } 61 | } 62 | .function{ 63 | margin-top: 25px; 64 | display: flex; 65 | flex-direction: row; 66 | color: #ffffff; 67 | .function-sub{ 68 | padding-left: 52px; 69 | flex: 1; 70 | font-size: 13px; 71 | font-weight: 300; 72 | position: relative; 73 | >i{ 74 | position: absolute; 75 | top: 0; 76 | left: 20px; 77 | } 78 | } 79 | } 80 | } 81 | 82 | .sidebar-list{ 83 | padding-bottom: 20px; 84 | background: #f9f9f9; 85 | .sidebar-list-first{ 86 | background: #f9f9f9; 87 | color: #00A2EA; 88 | height: 47px; 89 | line-height: 47px; 90 | font-size: 15px; 91 | padding-left: 55px; 92 | position: relative; 93 | >i{ 94 | color: #00A2EA; 95 | font-size: 20px; 96 | position: absolute; 97 | top: 0px; 98 | left: 20px; 99 | } 100 | } 101 | .sidebar-list-li{ 102 | height: 47px; 103 | line-height: 47px; 104 | display: flex; 105 | flex-direction: row; 106 | padding-left: 15px; 107 | >p{ 108 | flex: 1; 109 | font-size: 14px; 110 | color: #2c3e50; 111 | } 112 | >div{ 113 | padding-right: 40px; 114 | font-size: 25px; 115 | font-weight: 200; 116 | color: #868686; 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /app/css/slick-theme.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | // Default Variables 4 | 5 | // Slick icon entity codes outputs the following 6 | // "\2190" outputs ascii character "←" 7 | // "\2192" outputs ascii character "→" 8 | // "\2022" outputs ascii character "•" 9 | 10 | $slick-font-path: "./fonts/" !default; 11 | $slick-font-family: "slick" !default; 12 | $slick-loader-path: "./" !default; 13 | $slick-arrow-color: white !default; 14 | $slick-dot-color: black !default; 15 | $slick-dot-color-active: $slick-dot-color !default; 16 | $slick-prev-character: "\2190" !default; 17 | $slick-next-character: "\2192" !default; 18 | $slick-dot-character: "\2022" !default; 19 | $slick-dot-size: 6px !default; 20 | $slick-opacity-default: 0.75 !default; 21 | $slick-opacity-on-hover: 1 !default; 22 | $slick-opacity-not-active: 0.25 !default; 23 | 24 | //@function slick-image-url($url) { 25 | // @if function-exists(image-url) { 26 | // @return image-url($url); 27 | // } 28 | // @else { 29 | // @return url($slick-loader-path + $url); 30 | // } 31 | //} 32 | // 33 | //@function slick-font-url($url) { 34 | // @if function-exists(font-url) { 35 | // @return font-url($url); 36 | // } 37 | // @else { 38 | // @return url($slick-font-path + $url); 39 | // } 40 | //} 41 | // 42 | ///* Slider */ 43 | // 44 | //.slick-list { 45 | // .slick-loading & { 46 | // background: #fff slick-image-url("ajax-loader.gif") center center no-repeat; 47 | // } 48 | //} 49 | // 50 | ///* Icons */ 51 | //@if $slick-font-family == "slick" { 52 | // @font-face { 53 | // font-family: "slick"; 54 | // src: slick-font-url("slick.eot"); 55 | // src: slick-font-url("slick.eot?#iefix") format("embedded-opentype"), slick-font-url("slick.woff") format("woff"), slick-font-url("slick.ttf") format("truetype"), slick-font-url("slick.svg#slick") format("svg"); 56 | // font-weight: normal; 57 | // font-style: normal; 58 | // } 59 | //} 60 | 61 | /* Arrows */ 62 | 63 | .slick-prev, 64 | .slick-next { 65 | position: absolute; 66 | display: block; 67 | height: 20px; 68 | width: 20px; 69 | line-height: 0px; 70 | font-size: 0px; 71 | cursor: pointer; 72 | background: transparent; 73 | color: transparent; 74 | top: 50%; 75 | -webkit-transform: translate(0, -50%); 76 | -ms-transform: translate(0, -50%); 77 | transform: translate(0, -50%); 78 | padding: 0; 79 | border: none; 80 | outline: none; 81 | &:hover, &:focus { 82 | outline: none; 83 | background: transparent; 84 | color: transparent; 85 | &:before { 86 | opacity: $slick-opacity-on-hover; 87 | } 88 | } 89 | &.slick-disabled:before { 90 | opacity: $slick-opacity-not-active; 91 | } 92 | &:before { 93 | font-family: $slick-font-family; 94 | font-size: 20px; 95 | line-height: 1; 96 | color: $slick-arrow-color; 97 | opacity: $slick-opacity-default; 98 | -webkit-font-smoothing: antialiased; 99 | -moz-osx-font-smoothing: grayscale; 100 | } 101 | } 102 | 103 | .slick-prev { 104 | left: -25px; 105 | [dir="rtl"] & { 106 | left: auto; 107 | right: -25px; 108 | } 109 | &:before { 110 | content: $slick-prev-character; 111 | [dir="rtl"] & { 112 | content: $slick-next-character; 113 | } 114 | } 115 | } 116 | 117 | .slick-next { 118 | right: -25px; 119 | [dir="rtl"] & { 120 | left: -25px; 121 | right: auto; 122 | } 123 | &:before { 124 | content: $slick-next-character; 125 | [dir="rtl"] & { 126 | content: $slick-prev-character; 127 | } 128 | } 129 | } 130 | 131 | /* Dots */ 132 | 133 | .slick-dotted.slick-slider { 134 | margin-bottom: 30px; 135 | } 136 | 137 | .slick-dots { 138 | position: absolute; 139 | bottom: -25px; 140 | list-style: none; 141 | display: block; 142 | text-align: center; 143 | padding: 0; 144 | margin: 0; 145 | width: 100%; 146 | li { 147 | position: relative; 148 | display: inline-block; 149 | height: 20px; 150 | width: 20px; 151 | margin: 0 5px; 152 | padding: 0; 153 | cursor: pointer; 154 | button { 155 | border: 0; 156 | background: transparent; 157 | display: block; 158 | height: 20px; 159 | width: 20px; 160 | outline: none; 161 | line-height: 0px; 162 | font-size: 0px; 163 | color: transparent; 164 | padding: 5px; 165 | cursor: pointer; 166 | &:hover, &:focus { 167 | outline: none; 168 | &:before { 169 | opacity: $slick-opacity-on-hover; 170 | } 171 | } 172 | &:before { 173 | display: block; 174 | position: absolute; 175 | top: 0; 176 | left: 0; 177 | //content: $slick-dot-character; 178 | content: ''; 179 | width: 6px; 180 | height: 6px; 181 | background: #5a5a5a; 182 | border-radius: 50%; 183 | //font-family: $slick-font-family; 184 | //font-size: $slick-dot-size; 185 | line-height: 20px; 186 | text-align: center; 187 | color: $slick-dot-color; 188 | opacity: $slick-opacity-not-active; 189 | -webkit-font-smoothing: antialiased; 190 | -moz-osx-font-smoothing: grayscale; 191 | } 192 | } 193 | &.slick-active button:before { 194 | color: $slick-dot-color-active; 195 | opacity: $slick-opacity-default; 196 | } 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /app/css/slick.scss: -------------------------------------------------------------------------------- 1 | /* Slider */ 2 | 3 | .slick-slider { 4 | position: relative; 5 | display: block; 6 | box-sizing: border-box; 7 | -webkit-touch-callout: none; 8 | -webkit-user-select: none; 9 | -khtml-user-select: none; 10 | -moz-user-select: none; 11 | -ms-user-select: none; 12 | user-select: none; 13 | -ms-touch-action: pan-y; 14 | touch-action: pan-y; 15 | -webkit-tap-highlight-color: transparent; 16 | } 17 | .slick-list { 18 | position: relative; 19 | overflow: hidden; 20 | display: block; 21 | margin: 0; 22 | padding: 0; 23 | 24 | &:focus { 25 | outline: none; 26 | } 27 | 28 | &.dragging { 29 | cursor: pointer; 30 | cursor: hand; 31 | } 32 | } 33 | .slick-slider .slick-track, 34 | .slick-slider .slick-list { 35 | -webkit-transform: translate3d(0, 0, 0); 36 | -moz-transform: translate3d(0, 0, 0); 37 | -ms-transform: translate3d(0, 0, 0); 38 | -o-transform: translate3d(0, 0, 0); 39 | transform: translate3d(0, 0, 0); 40 | } 41 | 42 | .slick-track { 43 | position: relative; 44 | left: 0; 45 | top: 0; 46 | display: block; 47 | 48 | &:before, 49 | &:after { 50 | content: ""; 51 | display: table; 52 | } 53 | 54 | &:after { 55 | clear: both; 56 | } 57 | 58 | .slick-loading & { 59 | visibility: hidden; 60 | } 61 | } 62 | .slick-slide { 63 | float: left; 64 | height: 100%; 65 | min-height: 1px; 66 | [dir="rtl"] & { 67 | float: right; 68 | } 69 | img { 70 | display: block; 71 | } 72 | &.slick-loading img { 73 | display: none; 74 | } 75 | 76 | display: none; 77 | 78 | &.dragging img { 79 | pointer-events: none; 80 | } 81 | 82 | .slick-initialized & { 83 | display: block; 84 | } 85 | 86 | .slick-loading & { 87 | visibility: hidden; 88 | } 89 | 90 | .slick-vertical & { 91 | display: block; 92 | height: auto; 93 | border: 1px solid transparent; 94 | } 95 | } 96 | .slick-arrow.slick-hidden { 97 | display: none; 98 | } 99 | -------------------------------------------------------------------------------- /app/css/slider.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Swiper 3.3.1 3 | * Most modern mobile touch slider and framework with hardware accelerated transitions 4 | * 5 | * http://www.idangero.us/swiper/ 6 | * 7 | * Copyright 2016, Vladimir Kharlampidi 8 | * The iDangero.us 9 | * http://www.idangero.us/ 10 | * 11 | * Licensed under MIT 12 | * 13 | * Released on: February 7, 2016 14 | */ 15 | .swiper-container{margin:0 auto;position:relative;overflow:hidden;z-index:1}.swiper-container-no-flexbox .swiper-slide{float:left}.swiper-container-vertical>.swiper-wrapper{-webkit-box-orient:vertical;-moz-box-orient:vertical;-ms-flex-direction:column;-webkit-flex-direction:column;flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.swiper-container-android .swiper-slide,.swiper-wrapper{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-o-transform:translate(0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.swiper-container-multirow>.swiper-wrapper{-webkit-box-lines:multiple;-moz-box-lines:multiple;-ms-flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-wrap:wrap}.swiper-container-free-mode>.swiper-wrapper{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out;margin:0 auto}.swiper-slide{-webkit-flex-shrink:0;-ms-flex:0 0 auto;flex-shrink:0;width:100%;height:100%;position:relative}.swiper-container-autoheight,.swiper-container-autoheight .swiper-slide{height:auto}.swiper-container-autoheight .swiper-wrapper{-webkit-box-align:start;-ms-flex-align:start;-webkit-align-items:flex-start;align-items:flex-start;-webkit-transition-property:-webkit-transform,height;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform,height}.swiper-container .swiper-notification{position:absolute;left:0;top:0;pointer-events:none;opacity:0;z-index:-1000}.swiper-wp8-horizontal{-ms-touch-action:pan-y;touch-action:pan-y}.swiper-wp8-vertical{-ms-touch-action:pan-x;touch-action:pan-x}.swiper-button-next,.swiper-button-prev{position:absolute;top:50%;width:27px;height:44px;margin-top:-22px;z-index:10;cursor:pointer;-moz-background-size:27px 44px;-webkit-background-size:27px 44px;background-size:27px 44px;background-position:center;background-repeat:no-repeat}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-prev,.swiper-container-rtl .swiper-button-next{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");left:10px;right:auto}.swiper-button-prev.swiper-button-black,.swiper-container-rtl .swiper-button-next.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-prev.swiper-button-white,.swiper-container-rtl .swiper-button-next.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next,.swiper-container-rtl .swiper-button-prev{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");right:10px;left:auto}.swiper-button-next.swiper-button-black,.swiper-container-rtl .swiper-button-prev.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next.swiper-button-white,.swiper-container-rtl .swiper-button-prev.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-pagination{position:absolute;text-align:center;-webkit-transition:.3s;-moz-transition:.3s;-o-transition:.3s;transition:.3s;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0);z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-container-horizontal>.swiper-pagination-bullets,.swiper-pagination-custom,.swiper-pagination-fraction{bottom:10px;left:0;width:100%}.swiper-pagination-bullet{width:8px;height:8px;display:inline-block;border-radius:100%;background:#000;opacity:.2}button.swiper-pagination-bullet{border:none;margin:0;padding:0;box-shadow:none;-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;appearance:none}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-white .swiper-pagination-bullet{background:#fff}.swiper-pagination-bullet-active{opacity:1;background:#007aff}.swiper-pagination-white .swiper-pagination-bullet-active{background:#fff}.swiper-pagination-black .swiper-pagination-bullet-active{background:#000}.swiper-container-vertical>.swiper-pagination-bullets{right:10px;top:50%;-webkit-transform:translate3d(0,-50%,0);-moz-transform:translate3d(0,-50%,0);-o-transform:translate(0,-50%);-ms-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.swiper-container-vertical>.swiper-pagination-bullets .swiper-pagination-bullet{margin:5px 0;display:block}.swiper-container-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 5px}.swiper-pagination-progress{background:rgba(0,0,0,.25);position:absolute}.swiper-pagination-progress .swiper-pagination-progressbar{background:#007aff;position:absolute;left:0;top:0;width:100%;height:100%;-webkit-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0);-webkit-transform-origin:left top;-moz-transform-origin:left top;-ms-transform-origin:left top;-o-transform-origin:left top;transform-origin:left top}.swiper-container-rtl .swiper-pagination-progress .swiper-pagination-progressbar{-webkit-transform-origin:right top;-moz-transform-origin:right top;-ms-transform-origin:right top;-o-transform-origin:right top;transform-origin:right top}.swiper-container-horizontal>.swiper-pagination-progress{width:100%;height:4px;left:0;top:0}.swiper-container-vertical>.swiper-pagination-progress{width:4px;height:100%;left:0;top:0}.swiper-pagination-progress.swiper-pagination-white{background:rgba(255,255,255,.5)}.swiper-pagination-progress.swiper-pagination-white .swiper-pagination-progressbar{background:#fff}.swiper-pagination-progress.swiper-pagination-black .swiper-pagination-progressbar{background:#000}.swiper-container-3d{-webkit-perspective:1200px;-moz-perspective:1200px;-o-perspective:1200px;perspective:1200px}.swiper-container-3d .swiper-cube-shadow,.swiper-container-3d .swiper-slide,.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top,.swiper-container-3d .swiper-wrapper{-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;transform-style:preserve-3d}.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}.swiper-container-3d .swiper-slide-shadow-left{background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-right{background-image:-webkit-gradient(linear,right top,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-top{background-image:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-bottom{background-image:-webkit-gradient(linear,left bottom,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-coverflow .swiper-wrapper,.swiper-container-flip .swiper-wrapper{-ms-perspective:1200px}.swiper-container-cube,.swiper-container-flip{overflow:visible}.swiper-container-cube .swiper-slide,.swiper-container-flip .swiper-slide{pointer-events:none;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden;z-index:1}.swiper-container-cube .swiper-slide .swiper-slide,.swiper-container-flip .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-active .swiper-slide-active,.swiper-container-flip .swiper-slide-active,.swiper-container-flip .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-container-cube .swiper-slide-shadow-bottom,.swiper-container-cube .swiper-slide-shadow-left,.swiper-container-cube .swiper-slide-shadow-right,.swiper-container-cube .swiper-slide-shadow-top,.swiper-container-flip .swiper-slide-shadow-bottom,.swiper-container-flip .swiper-slide-shadow-left,.swiper-container-flip .swiper-slide-shadow-right,.swiper-container-flip .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden}.swiper-container-cube .swiper-slide{visibility:hidden;-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%}.swiper-container-cube.swiper-container-rtl .swiper-slide{-webkit-transform-origin:100% 0;-moz-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-next,.swiper-container-cube .swiper-slide-next+.swiper-slide,.swiper-container-cube .swiper-slide-prev{pointer-events:auto;visibility:visible}.swiper-container-cube .swiper-cube-shadow{position:absolute;left:0;bottom:0;width:100%;height:100%;background:#000;opacity:.6;-webkit-filter:blur(50px);filter:blur(50px);z-index:0}.swiper-container-fade.swiper-container-free-mode .swiper-slide{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out}.swiper-container-fade .swiper-slide{pointer-events:none;-webkit-transition-property:opacity;-moz-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity}.swiper-container-fade .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-fade .swiper-slide-active,.swiper-container-fade .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-scrollbar{border-radius:10px;position:relative;-ms-touch-action:none;background:rgba(0,0,0,.1)}.swiper-container-horizontal>.swiper-scrollbar{position:absolute;left:1%;bottom:3px;z-index:50;height:5px;width:98%}.swiper-container-vertical>.swiper-scrollbar{position:absolute;right:3px;top:1%;z-index:50;width:5px;height:98%}.swiper-scrollbar-drag{height:100%;width:100%;position:relative;background:rgba(0,0,0,.5);border-radius:10px;left:0;top:0}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-lazy-preloader{width:42px;height:42px;position:absolute;left:50%;top:50%;margin-left:-21px;margin-top:-21px;z-index:10;-webkit-transform-origin:50%;-moz-transform-origin:50%;transform-origin:50%;-webkit-animation:swiper-preloader-spin 1s steps(12,end) infinite;-moz-animation:swiper-preloader-spin 1s steps(12,end) infinite;animation:swiper-preloader-spin 1s steps(12,end) infinite}.swiper-lazy-preloader:after{display:block;content:"";width:100%;height:100%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");background-position:50%;-webkit-background-size:100%;background-size:100%;background-repeat:no-repeat}.swiper-lazy-preloader-white:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}@-webkit-keyframes swiper-preloader-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes swiper-preloader-spin{100%{transform:rotate(360deg)}} 16 | 17 | .swiper-container{ 18 | height: 230px; 19 | } 20 | .swiper-slide{ 21 | background-size: 100%; 22 | background-position: center; 23 | background-repeat: no-repeat; 24 | position: relative; 25 | a { 26 | display: block; 27 | width: 100%; 28 | height: 100%; 29 | } 30 | .swiper-mask{ 31 | width: 100%; 32 | height: 100%; 33 | position: absolute; 34 | top: 0; 35 | left: 0; 36 | background-image: -webkit-linear-gradient(bottom, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.1) 40%, rgba(0,0,0,0.1) 100%); 37 | background-image: linear-gradient(bottom, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.1) 40%, rgba(0,0,0,0.1) 100%); 38 | } 39 | .slider-title{ 40 | position: absolute; 41 | bottom: 23px; 42 | line-height: 1.2; 43 | left: 0; 44 | padding: 0 18px; 45 | font-weight: 300; 46 | font-size: 21px; 47 | color: #ffffff; 48 | } 49 | } 50 | .swiper-pagination-bullet{ 51 | width: 6px; 52 | height: 6px; 53 | display: inline-block; 54 | border-radius: 100%; 55 | background: #5a5a5a; 56 | opacity: .8; 57 | } 58 | .swiper-pagination-bullet-active{ 59 | opacity: 1; 60 | background: #f4f5ff; 61 | } -------------------------------------------------------------------------------- /app/css/swiper-3.3.1.min.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Swiper 3.3.1 3 | * Most modern mobile touch slider and framework with hardware accelerated transitions 4 | * 5 | * http://www.idangero.us/swiper/ 6 | * 7 | * Copyright 2016, Vladimir Kharlampidi 8 | * The iDangero.us 9 | * http://www.idangero.us/ 10 | * 11 | * Licensed under MIT 12 | * 13 | * Released on: February 7, 2016 14 | */ 15 | .swiper-container{margin:0 auto;position:relative;overflow:hidden;z-index:1}.swiper-container-no-flexbox .swiper-slide{float:left}.swiper-container-vertical>.swiper-wrapper{-webkit-box-orient:vertical;-moz-box-orient:vertical;-ms-flex-direction:column;-webkit-flex-direction:column;flex-direction:column}.swiper-wrapper{position:relative;width:100%;height:100%;z-index:1;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex;-webkit-transition-property:-webkit-transform;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.swiper-container-android .swiper-slide,.swiper-wrapper{-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-o-transform:translate(0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.swiper-container-multirow>.swiper-wrapper{-webkit-box-lines:multiple;-moz-box-lines:multiple;-ms-flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-wrap:wrap}.swiper-container-free-mode>.swiper-wrapper{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out;margin:0 auto}.swiper-slide{-webkit-flex-shrink:0;-ms-flex:0 0 auto;flex-shrink:0;width:100%;height:100%;position:relative}.swiper-container-autoheight,.swiper-container-autoheight .swiper-slide{height:auto}.swiper-container-autoheight .swiper-wrapper{-webkit-box-align:start;-ms-flex-align:start;-webkit-align-items:flex-start;align-items:flex-start;-webkit-transition-property:-webkit-transform,height;-moz-transition-property:-moz-transform;-o-transition-property:-o-transform;-ms-transition-property:-ms-transform;transition-property:transform,height}.swiper-container .swiper-notification{position:absolute;left:0;top:0;pointer-events:none;opacity:0;z-index:-1000}.swiper-wp8-horizontal{-ms-touch-action:pan-y;touch-action:pan-y}.swiper-wp8-vertical{-ms-touch-action:pan-x;touch-action:pan-x}.swiper-button-next,.swiper-button-prev{position:absolute;top:50%;width:27px;height:44px;margin-top:-22px;z-index:10;cursor:pointer;-moz-background-size:27px 44px;-webkit-background-size:27px 44px;background-size:27px 44px;background-position:center;background-repeat:no-repeat}.swiper-button-next.swiper-button-disabled,.swiper-button-prev.swiper-button-disabled{opacity:.35;cursor:auto;pointer-events:none}.swiper-button-prev,.swiper-container-rtl .swiper-button-next{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");left:10px;right:auto}.swiper-button-prev.swiper-button-black,.swiper-container-rtl .swiper-button-next.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-prev.swiper-button-white,.swiper-container-rtl .swiper-button-next.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next,.swiper-container-rtl .swiper-button-prev{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E");right:10px;left:auto}.swiper-button-next.swiper-button-black,.swiper-container-rtl .swiper-button-prev.swiper-button-black{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E")}.swiper-button-next.swiper-button-white,.swiper-container-rtl .swiper-button-prev.swiper-button-white{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E")}.swiper-pagination{position:absolute;text-align:center;-webkit-transition:.3s;-moz-transition:.3s;-o-transition:.3s;transition:.3s;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0);z-index:10}.swiper-pagination.swiper-pagination-hidden{opacity:0}.swiper-container-horizontal>.swiper-pagination-bullets,.swiper-pagination-custom,.swiper-pagination-fraction{bottom:10px;left:0;width:100%}.swiper-pagination-bullet{width:8px;height:8px;display:inline-block;border-radius:100%;background:#000;opacity:.2}button.swiper-pagination-bullet{border:none;margin:0;padding:0;box-shadow:none;-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;appearance:none}.swiper-pagination-clickable .swiper-pagination-bullet{cursor:pointer}.swiper-pagination-white .swiper-pagination-bullet{background:#fff}.swiper-pagination-bullet-active{opacity:1;background:#007aff}.swiper-pagination-white .swiper-pagination-bullet-active{background:#fff}.swiper-pagination-black .swiper-pagination-bullet-active{background:#000}.swiper-container-vertical>.swiper-pagination-bullets{right:10px;top:50%;-webkit-transform:translate3d(0,-50%,0);-moz-transform:translate3d(0,-50%,0);-o-transform:translate(0,-50%);-ms-transform:translate3d(0,-50%,0);transform:translate3d(0,-50%,0)}.swiper-container-vertical>.swiper-pagination-bullets .swiper-pagination-bullet{margin:5px 0;display:block}.swiper-container-horizontal>.swiper-pagination-bullets .swiper-pagination-bullet{margin:0 5px}.swiper-pagination-progress{background:rgba(0,0,0,.25);position:absolute}.swiper-pagination-progress .swiper-pagination-progressbar{background:#007aff;position:absolute;left:0;top:0;width:100%;height:100%;-webkit-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0);-webkit-transform-origin:left top;-moz-transform-origin:left top;-ms-transform-origin:left top;-o-transform-origin:left top;transform-origin:left top}.swiper-container-rtl .swiper-pagination-progress .swiper-pagination-progressbar{-webkit-transform-origin:right top;-moz-transform-origin:right top;-ms-transform-origin:right top;-o-transform-origin:right top;transform-origin:right top}.swiper-container-horizontal>.swiper-pagination-progress{width:100%;height:4px;left:0;top:0}.swiper-container-vertical>.swiper-pagination-progress{width:4px;height:100%;left:0;top:0}.swiper-pagination-progress.swiper-pagination-white{background:rgba(255,255,255,.5)}.swiper-pagination-progress.swiper-pagination-white .swiper-pagination-progressbar{background:#fff}.swiper-pagination-progress.swiper-pagination-black .swiper-pagination-progressbar{background:#000}.swiper-container-3d{-webkit-perspective:1200px;-moz-perspective:1200px;-o-perspective:1200px;perspective:1200px}.swiper-container-3d .swiper-cube-shadow,.swiper-container-3d .swiper-slide,.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top,.swiper-container-3d .swiper-wrapper{-webkit-transform-style:preserve-3d;-moz-transform-style:preserve-3d;-ms-transform-style:preserve-3d;transform-style:preserve-3d}.swiper-container-3d .swiper-slide-shadow-bottom,.swiper-container-3d .swiper-slide-shadow-left,.swiper-container-3d .swiper-slide-shadow-right,.swiper-container-3d .swiper-slide-shadow-top{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none;z-index:10}.swiper-container-3d .swiper-slide-shadow-left{background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(right,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to left,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-right{background-image:-webkit-gradient(linear,right top,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(left,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to right,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-top{background-image:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(bottom,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to top,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-3d .swiper-slide-shadow-bottom{background-image:-webkit-gradient(linear,left bottom,left top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,0)));background-image:-webkit-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-moz-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:-o-linear-gradient(top,rgba(0,0,0,.5),rgba(0,0,0,0));background-image:linear-gradient(to bottom,rgba(0,0,0,.5),rgba(0,0,0,0))}.swiper-container-coverflow .swiper-wrapper,.swiper-container-flip .swiper-wrapper{-ms-perspective:1200px}.swiper-container-cube,.swiper-container-flip{overflow:visible}.swiper-container-cube .swiper-slide,.swiper-container-flip .swiper-slide{pointer-events:none;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden;z-index:1}.swiper-container-cube .swiper-slide .swiper-slide,.swiper-container-flip .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-active .swiper-slide-active,.swiper-container-flip .swiper-slide-active,.swiper-container-flip .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-container-cube .swiper-slide-shadow-bottom,.swiper-container-cube .swiper-slide-shadow-left,.swiper-container-cube .swiper-slide-shadow-right,.swiper-container-cube .swiper-slide-shadow-top,.swiper-container-flip .swiper-slide-shadow-bottom,.swiper-container-flip .swiper-slide-shadow-left,.swiper-container-flip .swiper-slide-shadow-right,.swiper-container-flip .swiper-slide-shadow-top{z-index:0;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;backface-visibility:hidden}.swiper-container-cube .swiper-slide{visibility:hidden;-webkit-transform-origin:0 0;-moz-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;width:100%;height:100%}.swiper-container-cube.swiper-container-rtl .swiper-slide{-webkit-transform-origin:100% 0;-moz-transform-origin:100% 0;-ms-transform-origin:100% 0;transform-origin:100% 0}.swiper-container-cube .swiper-slide-active,.swiper-container-cube .swiper-slide-next,.swiper-container-cube .swiper-slide-next+.swiper-slide,.swiper-container-cube .swiper-slide-prev{pointer-events:auto;visibility:visible}.swiper-container-cube .swiper-cube-shadow{position:absolute;left:0;bottom:0;width:100%;height:100%;background:#000;opacity:.6;-webkit-filter:blur(50px);filter:blur(50px);z-index:0}.swiper-container-fade.swiper-container-free-mode .swiper-slide{-webkit-transition-timing-function:ease-out;-moz-transition-timing-function:ease-out;-ms-transition-timing-function:ease-out;-o-transition-timing-function:ease-out;transition-timing-function:ease-out}.swiper-container-fade .swiper-slide{pointer-events:none;-webkit-transition-property:opacity;-moz-transition-property:opacity;-o-transition-property:opacity;transition-property:opacity}.swiper-container-fade .swiper-slide .swiper-slide{pointer-events:none}.swiper-container-fade .swiper-slide-active,.swiper-container-fade .swiper-slide-active .swiper-slide-active{pointer-events:auto}.swiper-scrollbar{border-radius:10px;position:relative;-ms-touch-action:none;background:rgba(0,0,0,.1)}.swiper-container-horizontal>.swiper-scrollbar{position:absolute;left:1%;bottom:3px;z-index:50;height:5px;width:98%}.swiper-container-vertical>.swiper-scrollbar{position:absolute;right:3px;top:1%;z-index:50;width:5px;height:98%}.swiper-scrollbar-drag{height:100%;width:100%;position:relative;background:rgba(0,0,0,.5);border-radius:10px;left:0;top:0}.swiper-scrollbar-cursor-drag{cursor:move}.swiper-lazy-preloader{width:42px;height:42px;position:absolute;left:50%;top:50%;margin-left:-21px;margin-top:-21px;z-index:10;-webkit-transform-origin:50%;-moz-transform-origin:50%;transform-origin:50%;-webkit-animation:swiper-preloader-spin 1s steps(12,end) infinite;-moz-animation:swiper-preloader-spin 1s steps(12,end) infinite;animation:swiper-preloader-spin 1s steps(12,end) infinite}.swiper-lazy-preloader:after{display:block;content:"";width:100%;height:100%;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");background-position:50%;-webkit-background-size:100%;background-size:100%;background-repeat:no-repeat}.swiper-lazy-preloader-white:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}@-webkit-keyframes swiper-preloader-spin{100%{-webkit-transform:rotate(360deg)}}@keyframes swiper-preloader-spin{100%{transform:rotate(360deg)}} -------------------------------------------------------------------------------- /app/css/zhihu_news_detail.scss: -------------------------------------------------------------------------------- 1 | .detail-content { 2 | article, 3 | aside, 4 | details, 5 | figcaption, 6 | figure, 7 | footer, 8 | header, 9 | hgroup, 10 | main, 11 | nav, 12 | section, 13 | summary { 14 | display: block; 15 | } 16 | audio, 17 | canvas, 18 | video { 19 | display: inline-block; 20 | } 21 | audio:not([controls]) { 22 | display: none; 23 | height: 0; 24 | } 25 | html { 26 | font-family: sans-serif; 27 | -webkit-text-size-adjust: 100%; 28 | } 29 | body { 30 | font-family: 'Helvetica Neue', Helvetica, Arial, Sans-serif; 31 | background: #fff; 32 | padding-top: 0; 33 | margin: 0; 34 | } 35 | a:focus { 36 | outline: thin dotted; 37 | } 38 | a:active, 39 | a:hover { 40 | outline: 0; 41 | } 42 | h1 { 43 | margin: .67em 0; 44 | } 45 | h1, 46 | h2, 47 | h3, 48 | h4, 49 | h5, 50 | h6 { 51 | font-size: 16px; 52 | } 53 | abbr[title] { 54 | border-bottom: 1px dotted; 55 | } 56 | hr { 57 | box-sizing: content-box; 58 | height: 0; 59 | } 60 | mark { 61 | background: #ff0; 62 | color: #000; 63 | } 64 | code, 65 | kbd, 66 | pre, 67 | samp { 68 | font-family: monospace,serif; 69 | font-size: 1em; 70 | } 71 | pre { 72 | white-space: pre-wrap; 73 | } 74 | q { 75 | quotes: \201C\201D\2018\2019; 76 | } 77 | small { 78 | font-size: 80%; 79 | } 80 | sub, 81 | sup { 82 | font-size: 75%; 83 | line-height: 0; 84 | position: relative; 85 | vertical-align: baseline; 86 | } 87 | sup { 88 | top: -0.5em; 89 | } 90 | sub { 91 | bottom: -0.25em; 92 | } 93 | img { 94 | border: 0; 95 | vertical-align: middle; 96 | color: transparent; 97 | font-size: 0; 98 | } 99 | svg:not(:root) { 100 | overflow: hidden; 101 | } 102 | figure { 103 | margin: 0; 104 | } 105 | fieldset { 106 | border: 1px solid silver; 107 | margin: 0 2px; 108 | padding: .35em .625em .75em; 109 | } 110 | legend { 111 | border: 0; 112 | padding: 0; 113 | } 114 | table { 115 | border-collapse: collapse; 116 | border-spacing: 0; 117 | overflow: hidden; 118 | } 119 | a { 120 | text-decoration: none; 121 | } 122 | blockquote { 123 | border-left: 3px solid #D0E5F2; 124 | font-style: normal; 125 | display: block; 126 | vertical-align: baseline; 127 | font-size: 100%; 128 | margin: .5em 0; 129 | padding: 0 0 0 1em; 130 | } 131 | ul, 132 | ol { 133 | padding-left: 20px; 134 | } 135 | .main-wrap { 136 | max-width: 100%; 137 | min-width: 300px; 138 | margin: 0 auto; 139 | } 140 | .content-wrap { 141 | overflow: hidden; 142 | background-color: #f9f9f9; 143 | } 144 | .content-wrap a { 145 | word-break: break-all; 146 | } 147 | .headline { 148 | border-bottom: 4px solid #f6f6f6; 149 | } 150 | .headline-title.onlyheading { 151 | margin: 20px 0; 152 | } 153 | .headline img { 154 | max-width: 100%; 155 | vertical-align: top; 156 | } 157 | .headline-background-link { 158 | line-height: 2em; 159 | position: relative; 160 | display: block; 161 | padding: 20px 45px 20px 20px !important; 162 | } 163 | .icon-arrow-right { 164 | position: absolute; 165 | top: 50%; 166 | right: 20px; 167 | background-image: url(http://static.daily.zhihu.com/img/share-icons.png); 168 | background-repeat: no-repeat; 169 | display: inline-block; 170 | vertical-align: middle; 171 | background-position: -70px -20px; 172 | width: 10px; 173 | height: 15px; 174 | margin-top: -7.5px; 175 | } 176 | .headline-background .heading { 177 | color: #999; 178 | font-size: 15px!important; 179 | margin-bottom: 8px; 180 | line-height: 1em; 181 | } 182 | .headline-background .heading-content { 183 | color: #444; 184 | font-size: 17px!important; 185 | line-height: 1.2em; 186 | } 187 | .headline-title { 188 | line-height: 1.2em; 189 | color: #000; 190 | font-size: 22px; 191 | margin: 20px 0 10px; 192 | padding: 0 20px!important; 193 | font-weight: bold; 194 | } 195 | .meta { 196 | white-space: nowrap; 197 | text-overflow: ellipsis; 198 | overflow: hidden; 199 | font-size: 16px; 200 | color: #b8b8b8; 201 | } 202 | .meta .source-icon { 203 | width: 20px; 204 | height: 20px; 205 | margin-right: 4px; 206 | } 207 | .meta .time { 208 | float: right; 209 | margin-top: 2px; 210 | } 211 | .content { 212 | color: #444; 213 | line-height: 1.6em; 214 | font-size: 17px; 215 | margin: 10px 0 20px; 216 | } 217 | .content img { 218 | max-width: 100%; 219 | display: block; 220 | margin: 30px auto; 221 | } 222 | 223 | .content img + img { 224 | margin-top: 15px; 225 | } 226 | 227 | .content img[src*="zhihu.com/equation"] { 228 | display: inline-block; 229 | margin: 0 3px; 230 | } 231 | .content a { 232 | color: #259; 233 | } 234 | .content a:hover { 235 | text-decoration: underline; 236 | } 237 | .view-more { 238 | margin-bottom: 25px; 239 | text-align: center; 240 | } 241 | .view-more a { 242 | font-size: 16px; 243 | display: inline-block; 244 | width: 125px; 245 | height: 30px; 246 | line-height: 30px; 247 | background: #f0f0f0; 248 | color: #B8B8B8; 249 | } 250 | .question { 251 | overflow: hidden; 252 | padding: 0 20px!important; 253 | } 254 | .question + .question { 255 | border-top: 5px solid #f6f6f6; 256 | } 257 | .question-title { 258 | line-height: 1.4em; 259 | color: #000; 260 | font-weight: 700; 261 | font-size: 18px; 262 | margin: 20px 0; 263 | } 264 | .meta .author { 265 | color: #444; 266 | font-weight: 700; 267 | } 268 | .answer + .answer { 269 | border-top: 2px solid #f6f6f6; 270 | padding-top: 20px; 271 | } 272 | .footer { 273 | text-align: center; 274 | color: #b8b8b8; 275 | font-size: 13px; 276 | padding: 20px 0; 277 | } 278 | .footer a { 279 | color: #b8b8b8; 280 | } 281 | .question .view-more a { 282 | width: 100%; 283 | display: block; 284 | } 285 | .hot-comment { 286 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 287 | } 288 | .comment-label { 289 | font-size: 16px; 290 | color: #333; 291 | line-height: 1.5em; 292 | font-weight: 700; 293 | border-top: 1px solid #eee; 294 | border-bottom: 1px solid #eee; 295 | margin: 0; 296 | padding: 9px 20px; 297 | } 298 | .comment-list { 299 | margin-bottom: 20px; 300 | } 301 | .comment-item { 302 | font-size: 15px; 303 | color: #666; 304 | border-bottom: 1px solid #eee; 305 | padding: 15px 20px; 306 | } 307 | .comment-meta { 308 | position: relative; 309 | margin-bottom: 10px; 310 | } 311 | .comment-meta .author { 312 | vertical-align: middle; 313 | color: #444; 314 | } 315 | .comment-meta .vote { 316 | position: absolute; 317 | color: #b8b8b8; 318 | font-size: 12px; 319 | right: 0; 320 | } 321 | .night .comment-label { 322 | color: #b8b8b8; 323 | border-top: 1px solid #303030; 324 | border-bottom: 1px solid #303030; 325 | } 326 | .night .comment-item { 327 | color: #7f7f7f; 328 | border-bottom: 1px solid #303030; 329 | } 330 | .icon-vote, 331 | .icon-voted { 332 | background-repeat: no-repeat; 333 | display: inline-block; 334 | vertical-align: 0; 335 | width: 11px; 336 | height: 12px; 337 | margin-right: 4px; 338 | background-image: url(http://static.daily.zhihu.com/img/app/Comment_Vote.png) !important; 339 | } 340 | .icon-voted { 341 | background-image: url(http://static.daily.zhihu.com/img/app/Comment_Voted.png) !important; 342 | } 343 | .night .icon-vote { 344 | background-image: url(http://static.daily.zhihu.com/img/app/Dark_Comment_Vote.png) !important; 345 | } 346 | .img-wrap .headline-title { 347 | bottom: 5px; 348 | } 349 | .img-wrap .img-source { 350 | right: 10px!important; 351 | font-size: 9px; 352 | } 353 | .global-header { 354 | position: static; 355 | } 356 | .button { 357 | width: 60px; 358 | } 359 | .button i { 360 | margin-right: 0; 361 | } 362 | .headline .img-place-holder { 363 | height: 0px; 364 | } 365 | .from-column { 366 | width: 280px; 367 | line-height: 30px; 368 | height: 30px; 369 | padding-left: 90px; 370 | color: #2aacec; 371 | background-image: url(http://static.daily.zhihu.com/img/News_Column_Entrance.png); 372 | box-sizing: border-box; 373 | margin: 0 20px 20px; 374 | } 375 | .from-column:active { 376 | background-image: url(http://static.daily.zhihu.com/img/News_Column_Entrance_Highlight.png); 377 | } 378 | .night .headline { 379 | border-bottom: 4px solid #303030; 380 | } 381 | .night img { 382 | -webkit-mask-image: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(0, 0, 0, 0.7)), to(rgba(0, 0, 0, 0.7))); 383 | } 384 | body.night, 385 | .night .content-wrap { 386 | background: #343434; 387 | } 388 | .night .answer + .answer { 389 | border-top: 2px solid #303030; 390 | } 391 | .night .question + .question { 392 | border-top: 4px solid #303030; 393 | } 394 | .night .view-more a { 395 | background: #292929; 396 | color: #666; 397 | } 398 | .night .icon-arrow-right { 399 | background-image: url(http://static.daily.zhihu.com/img/share-icons.png); 400 | background-repeat: no-repeat; 401 | display: inline-block; 402 | vertical-align: middle; 403 | background-position: -70px -35px; 404 | width: 10px; 405 | height: 15px; 406 | } 407 | .night blockquote, 408 | .night sup { 409 | border-left: 3px solid #666; 410 | } 411 | .night .content a { 412 | color: #698ebf; 413 | } 414 | .night .from-column { 415 | color: #2b82ac; 416 | background-image: url(http://static.daily.zhihu.com/img/Dark_News_Column_Entrance.png); 417 | } 418 | .night .from-column:active { 419 | background-image: url(http://static.daily.zhihu.com/img/Dark_News_Column_Entrance_Highlight.png); 420 | } 421 | .large .question-title { 422 | font-size: 24px; 423 | } 424 | .large .meta { 425 | font-size: 18px; 426 | } 427 | .large .content { 428 | font-size: 20px; 429 | } 430 | .large blockquote, 431 | .large sup { 432 | line-height: 1.6; 433 | } 434 | .meta .meta-item { 435 | -o-text-overflow: ellipsis; 436 | width: 39%; 437 | overflow: hidden; 438 | white-space: nowrap; 439 | text-overflow: ellipsis; 440 | display: inline-block; 441 | color: #929292; 442 | margin-right: 7px; 443 | } 444 | .headline .meta { 445 | white-space: nowrap; 446 | text-overflow: ellipsis; 447 | overflow: hidden; 448 | font-size: 11px; 449 | color: #b8b8b8; 450 | margin: 15px 0; 451 | padding: 0 20px; 452 | } 453 | .headline .meta a, 454 | .headline .meta a:hover { 455 | padding-left: 1em; 456 | margin-top: 2px; 457 | float: right; 458 | font-size: 11px; 459 | color: #0066cf; 460 | text-decoration: none; 461 | } 462 | .highlight { 463 | width: auto; 464 | overflow: auto; 465 | word-wrap: normal; 466 | } 467 | .highlight::-webkit-scrollbar { 468 | width: 6px; 469 | height: 6px; 470 | } 471 | .highlight code { 472 | overflow: auto; 473 | } 474 | .highlight::-webkit-scrollbar-thumb:horizontal { 475 | border-radius: 6px; 476 | background-color: rgba(0,0,0,.5); 477 | } 478 | .highlight::-webkit-scrollbar-thumb:horizontal:hover { 479 | background-color: rgba(0,0,0,.6); 480 | } 481 | .highlight pre { 482 | margin: 0; 483 | white-space: pre; 484 | } 485 | .highlight .hll { 486 | background-color: #ffc; 487 | } 488 | .highlight .err { 489 | color: #a61717; 490 | background-color: #e3d2d2; 491 | } 492 | .highlight .cp { 493 | color: #999; 494 | font-weight: 700; 495 | } 496 | .highlight .cs { 497 | color: #999; 498 | font-weight: 700; 499 | font-style: italic; 500 | } 501 | .highlight .gd { 502 | color: #000; 503 | background-color: #fdd; 504 | } 505 | .highlight .gi { 506 | color: #000; 507 | background-color: #dfd; 508 | } 509 | .highlight .gu { 510 | color: #aaa; 511 | } 512 | .highlight .ni { 513 | color: purple; 514 | } 515 | .highlight .nt { 516 | color: navy; 517 | } 518 | .highlight .w { 519 | color: #bbb; 520 | } 521 | .highlight .sr { 522 | color: olive; 523 | } 524 | [hidden], 525 | .button span { 526 | display: none; 527 | } 528 | b, 529 | strong, 530 | .highlight .k, 531 | .highlight .o, 532 | .highlight .gs, 533 | .highlight .kc, 534 | .highlight .kd, 535 | .highlight .kn, 536 | .highlight .kp, 537 | .highlight .kr, 538 | .highlight .ow { 539 | font-weight: 700; 540 | } 541 | dfn, 542 | .highlight .ge { 543 | font-style: italic; 544 | } 545 | .meta span, 546 | .meta .source { 547 | vertical-align: middle; 548 | } 549 | .meta .avatar, 550 | .comment-meta .avatar { 551 | width: 20px; 552 | height: 20px; 553 | border-radius: 2px; 554 | margin-right: 5px; 555 | } 556 | .meta .bio, 557 | .highlight .gh, 558 | .highlight .bp { 559 | color: #999; 560 | } 561 | .night .comment-meta .author, 562 | .night .content, 563 | .night .meta .author, 564 | .highlight .go { 565 | color: #888; 566 | } 567 | .night .headline-title, 568 | .night .headline-background .heading-content, 569 | .night .question-title { 570 | color: #B8B8B8; 571 | } 572 | .highlight .c, 573 | .highlight .cm, 574 | .highlight .c1 { 575 | color: #998; 576 | font-style: italic; 577 | } 578 | .highlight .gr, 579 | .highlight .gt { 580 | color: #a00; 581 | } 582 | .highlight .gp, 583 | .highlight .nn { 584 | color: #555; 585 | } 586 | .highlight .kt, 587 | .highlight .nc { 588 | color: #458; 589 | font-weight: 700; 590 | } 591 | .highlight .m, 592 | .highlight .mf, 593 | .highlight .mh, 594 | .highlight .mi, 595 | .highlight .mo, 596 | .highlight .il { 597 | color: #099; 598 | } 599 | .highlight .s, 600 | .highlight .sb, 601 | .highlight .sc, 602 | .highlight .sd, 603 | .highlight .s2, 604 | .highlight .se, 605 | .highlight .sh, 606 | .highlight .si, 607 | .highlight .sx, 608 | .highlight .s1, 609 | .highlight .ss { 610 | color: #d32; 611 | } 612 | .highlight .na, 613 | .highlight .nb, 614 | .highlight .no, 615 | .highlight .nv, 616 | .highlight .vc, 617 | .highlight .vg, 618 | .highlight .vi { 619 | color: teal; 620 | } 621 | .highlight .ne, 622 | .highlight .nf { 623 | color: #900; 624 | font-weight: 700; 625 | } 626 | .answer h1, 627 | .answer h2, 628 | .answer h3, 629 | .answer h4, 630 | .answer h5 { 631 | font-size: 19px; 632 | } 633 | @media only screen and (-webkit-min-device-pixel-ratio2), only screen and (min-device-pixel-ratio2) { 634 | .icon-arrow-right { 635 | background-image: url(http://static.daily.zhihu.com/img/share-icons@2x.png); 636 | -webkit-background-size: 82px 55px; 637 | background-size: 82px 55px; 638 | } 639 | .icon-vote, 640 | .icon-voted { 641 | background-image: url(http://static.daily.zhihu.com/img/app/Comment_Vote@2x.png) !important; 642 | background-size: 11px 12px; 643 | } 644 | .icon-voted { 645 | background-image: url(http://static.daily.zhihu.com/img/app/Comment_Voted@2x.png) !important; 646 | } 647 | .night .icon-vote { 648 | background-image: url(http://static.daily.zhihu.com/img/app/Dark_Comment_Vote@2x.png) !important; 649 | } 650 | .from-column { 651 | background-image: url(http://static.daily.zhihu.com/img/News_Column_Entrance@2x.png) !important; 652 | background-size: 280px 30px; 653 | } 654 | .from-column:active { 655 | background-image: url(http://static.daily.zhihu.com/img/News_Column_Entrance_Highlight@2x.png) !important; 656 | } 657 | .night .from-column { 658 | color: #2b82ac; 659 | background-image: url(http://static.daily.zhihu.com/img/Dark_News_Column_Entrance@2x.png) !important; 660 | } 661 | .night .from-column:active { 662 | background-image: url(http://static.daily.zhihu.com/img/Dark_News_Column_Entrance_Highlight@2x.png) !important; 663 | } 664 | } 665 | .meta .meta-item { 666 | width: 39%; 667 | overflow: hidden; 668 | white-space: nowrap; 669 | text-overflow: ellipsis; 670 | display: inline-block; 671 | color: #929292; 672 | margin-right: 7px; 673 | } 674 | .headline .meta { 675 | white-space: nowrap; 676 | text-overflow: ellipsis; 677 | overflow: hidden; 678 | font-size: 11px; 679 | color: #b8b8b8; 680 | margin: 20px 0; 681 | padding: 0 20px; 682 | } 683 | .headline .meta a, 684 | .headline .meta a:hover { 685 | margin-top: 2px; 686 | float: right; 687 | font-size: 11px; 688 | color: #0066cf; 689 | text-decoration: none; 690 | } 691 | .answer h1, 692 | .answer h2, 693 | .answer h3, 694 | .answer h4, 695 | .answer h5 { 696 | font-size: 19px; 697 | } 698 | .origin-source, 699 | a.origin-source:link { 700 | display: block; 701 | margin: 25px 0; 702 | height: 50px; 703 | overflow: hidden; 704 | background: #f0f0f0; 705 | color: #888; 706 | position: relative; 707 | -webkit-touch-callout: none; 708 | } 709 | .origin-source .source-logo, 710 | a.origin-source:link .source-logo { 711 | float: left; 712 | width: 50px; 713 | height: 50px; 714 | margin-right: 10px; 715 | } 716 | .origin-source .text, 717 | a.origin-source:link .text { 718 | line-height: 50px; 719 | height: 50px; 720 | font-size: 13px; 721 | } 722 | .origin-source.with-link .text { 723 | color: #333; 724 | } 725 | .origin-source.with-link:after { 726 | display: block; 727 | position: absolute; 728 | border-color: transparent transparent transparent #f0f0f0; 729 | border-width: 7px; 730 | border-style: solid; 731 | height: 0; 732 | width: 0; 733 | top: 18px; 734 | right: 4px; 735 | line-height: 0; 736 | content: ""; 737 | } 738 | .origin-source.with-link:before { 739 | display: block; 740 | height: 0; 741 | width: 0; 742 | position: absolute; 743 | top: 18px; 744 | right: 3px; 745 | border-color: transparent transparent transparent #000; 746 | border-width: 7px; 747 | border-style: solid; 748 | line-height: 0; 749 | content: ""; 750 | } 751 | .origin-source-wrap { 752 | position: relative; 753 | background: #f0f0f0; 754 | } 755 | .origin-source-wrap .focus-link { 756 | position: absolute; 757 | right: 0; 758 | top: 0; 759 | width: 45px; 760 | color: #00a2ed; 761 | height: 50px; 762 | display: none; 763 | text-align: center; 764 | font-size: 12px; 765 | -webkit-touch-callout: none; 766 | } 767 | .origin-source-wrap .focus-link .btn-label { 768 | text-align: center; 769 | display: block; 770 | margin-top: 8px; 771 | border-left: solid 1px #ccc; 772 | height: 34px; 773 | line-height: 34px; 774 | } 775 | .origin-source-wrap.unfocused .focus-link { 776 | display: block; 777 | } 778 | .origin-source-wrap.unfocused .origin-source:before, 779 | .origin-source-wrap.unfocused .origin-source:after { 780 | display: none; 781 | } 782 | .night .origin-source-wrap { 783 | background: #292929; 784 | } 785 | .night .origin-source-wrap .focus-link { 786 | color: #116f9e; 787 | } 788 | .night .origin-source-wrap .btn-label { 789 | border-left: solid 1px #3f3f3f; 790 | } 791 | .night .origin-source, 792 | .night .origin-source.with-link { 793 | background: #292929; 794 | color: #666; 795 | } 796 | .night .origin-source .text, 797 | .night .origin-source.with-link .text { 798 | color: #666; 799 | } 800 | .night .origin-source.with-link:after { 801 | border-color: transparent transparent transparent #292929; 802 | } 803 | .night .origin-source.with-link:before { 804 | border-color: transparent transparent transparent #666; 805 | } 806 | /* ==== */ 807 | .question-title { 808 | color: #494b4d; 809 | } 810 | 811 | blockquote { 812 | color: #9da3a6; 813 | border-left: 3px solid #Dfe3e6; 814 | } 815 | 816 | .content a { 817 | color: #4786b3; 818 | } 819 | 820 | .content { 821 | font-size: 17px; 822 | color: #616466; 823 | } 824 | 825 | .content-wrap { 826 | background: #fff; 827 | } 828 | 829 | hr { 830 | margin: 30px 0; 831 | border-top-width: 0; 832 | } 833 | 834 | 835 | p { 836 | margin: 20px 0 !important; 837 | } 838 | 839 | .dudu-night .content { 840 | color: #797b80; 841 | } 842 | 843 | .dudu-night hr { 844 | color: #27282b; 845 | border-color: #27282b; 846 | } 847 | .dudu-night .meta .author, 848 | .dudu-night .meta .bio { 849 | color: #555659; 850 | } 851 | .dudu-night .headline-title, 852 | .dudu-night .headline-background .heading-content, 853 | .dudu-night .question-title { 854 | color: #919499; 855 | } 856 | 857 | .dudu-night .headline { 858 | border-bottom: none; 859 | } 860 | .dudu-night img { 861 | -webkit-mask-image: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(0, 0, 0, 0.7)), to(rgba(0, 0, 0, 0.7))); 862 | } 863 | body.dudu-night, 864 | .dudu-night .content-wrap { 865 | background: #1d1e1f; 866 | } 867 | .dudu-night .answer + .answer { 868 | border-top: 2px solid #27282b; 869 | } 870 | .dudu-night .question + .question { 871 | border-top: 4px solid #27282b; 872 | } 873 | .dudu-night .view-more a { 874 | background: #1d1e1f; 875 | color: #396280; 876 | } 877 | .dudu-night .icon-arrow-right { 878 | background-image: url(http://static.daily.zhihu.com/img/share-icons.png); 879 | background-repeat: no-repeat; 880 | display: inline-block; 881 | vertical-align: middle; 882 | background-position: -70px -35px; 883 | width: 10px; 884 | height: 15px; 885 | } 886 | .dudu-night blockquote, 887 | .dudu-night sup { 888 | border-left: 3px solid #2e3033; 889 | color: #555659; 890 | } 891 | .dudu-night .content a { 892 | color: #396280; 893 | } 894 | 895 | .dudu-night img { 896 | opacity: 0.7; 897 | } 898 | 899 | .dudu-night .from-column { 900 | color: #2b82ac; 901 | background-image: url(http://static.daily.zhihu.com/img/Dark_News_Column_Entrance.png); 902 | } 903 | .dudu-night .from-column:active { 904 | background-image: url(http://static.daily.zhihu.com/img/Dark_News_Column_Entrance_Highlight.png); 905 | } 906 | 907 | /*禁用头部下面的分隔线*/ 908 | .dudu .headline { 909 | border-bottom: none; 910 | } 911 | 912 | .dudu-night .origin-source, 913 | .dudu-night a.origin-source:link { 914 | background: #222324; 915 | } 916 | 917 | .dudu-night .origin-source.with-link .text { 918 | color: #797b80; 919 | } 920 | .dudu-night .origin-source.with-link:after { 921 | border-color: transparent transparent transparent #797b80; 922 | } 923 | 924 | } -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 知乎日报 9 | 10 | 11 |
    12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/main.dev.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/11/18. 3 | */ 4 | 'use strict'; 5 | // 库 6 | import 'lib-flexible' 7 | import React from 'react'; 8 | import { Router, Route, hashHistory, IndexRoute } from 'react-router'; 9 | import { render } from 'react-dom'; 10 | import thunk from 'redux-thunk'; 11 | import axios from 'axios'; 12 | import { createStore, applyMiddleware,compose } from 'redux' 13 | import DevTools from './DevTools' 14 | import reducer from './redux/reducer' 15 | import { Provider } from 'react-redux' 16 | 17 | 18 | const enhancer = compose( 19 | DevTools.instrument() 20 | ); 21 | console.log(process.env) 22 | const store = createStore(reducer, enhancer, applyMiddleware(thunk)) 23 | // const store = createStore(reducer, applyMiddleware(thunk)) 24 | 25 | window.axios = axios 26 | 27 | // 组件 28 | import List from './view/list.jsx' 29 | import Detail from './view/detail.jsx' 30 | import listDefault from './components/list-default.jsx' 31 | import ListTheme from './components/list-theme.jsx' 32 | import Editor from './view/editor.jsx' 33 | import Author from './view/author.jsx' 34 | import Comments from './view/comments.jsx' 35 | import Section from './view/section.jsx' 36 | import Recommender from './view/recommender.jsx' 37 | 38 | import './css/main.scss'; 39 | 40 | 41 | 42 | render( 43 | 44 |
    45 | 46 | 47 | 48 | 49 | 50 | {/**/} 51 | 52 | {/**/} 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
    61 |
    , 62 | document.getElementById('app') 63 | ); 64 | -------------------------------------------------------------------------------- /app/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/11/18. 3 | */ 4 | 'use strict'; 5 | // 库 6 | import 'lib-flexible' 7 | import React from 'react'; 8 | import { Router, Route, hashHistory, IndexRoute } from 'react-router'; 9 | import { render } from 'react-dom'; 10 | import thunk from 'redux-thunk'; 11 | import axios from 'axios'; 12 | import { createStore, applyMiddleware,compose } from 'redux' 13 | import DevTools from './DevTools' 14 | import reducer from './redux/reducer' 15 | import { Provider } from 'react-redux' 16 | 17 | const enhancer = compose( 18 | DevTools.instrument() 19 | ); 20 | 21 | // const store = createStore(reducer, enhancer, applyMiddleware(thunk)) 22 | const store = createStore(reducer, applyMiddleware(thunk)) 23 | 24 | window.axios = axios 25 | 26 | // 组件 27 | import List from './view/list.jsx' 28 | import Detail from './view/detail.jsx' 29 | import listDefault from './components/list-default.jsx' 30 | import ListTheme from './components/list-theme.jsx' 31 | import Editor from './view/editor.jsx' 32 | import Author from './view/author.jsx' 33 | import Comments from './view/comments.jsx' 34 | import Recommender from './view/recommender.jsx' 35 | import Section from './view/section.jsx' 36 | 37 | import './css/main.scss'; 38 | 39 | 40 | 41 | render( 42 | 43 |
    44 | 45 | 46 | 47 | 48 | 49 | {/**/} 50 | 51 | {/**/} 52 | 53 | 54 | 55 | 56 | 57 | 58 | {/**/} 59 |
    60 |
    , 61 | document.getElementById('app') 62 | ); 63 | -------------------------------------------------------------------------------- /app/redux/action/acitontype.js: -------------------------------------------------------------------------------- 1 | export const A = 'FETCH_DATA_START'; 2 | export const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS'; 3 | export const FETCH_DATA_ERROR = 'FETCH_DATA_ERROR'; 4 | export const CLICK_START = 'CLICK_START'; 5 | export const CLICK_COMPELETE = 'CLICK_COMPELETE'; 6 | export const INIT_STATE = 'INIT_STATE'; 7 | export const SAVE_CHECKED_DATA = 'SAVE_CHECKED_DATA'; 8 | export const RESET_ALL_LOADING = 'RESET_ALL_LOADING'; 9 | export const CHANGE_EDIT_TABLE_STATUS = 'CHANGE_EDIT_TABLE_STATUS'; 10 | export const SHOW_MODAL = 'SHOW_MODAL'; 11 | export const DISMISS_MODAL = 'DISMISS_MODAL'; 12 | // export const INIT_ADD_PRICE_INPUT = 'INIT_ADD_PRICE_INPUT'; 13 | export const CHANGE_INPUT_EDITABLE = 'CHANGE_INPUT_EDITABLE'; 14 | export const CHANGE_INPUT_DISABLE = 'CHANGE_INPUT_DISABLE'; 15 | -------------------------------------------------------------------------------- /app/redux/action/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/9. 3 | */ 4 | 5 | import {axiosGet} from '../../util/ajax' 6 | export const getSidebarList = () => { 7 | return { 8 | type: 'GET_SIDEBAR_LIST' 9 | } 10 | } 11 | 12 | export const getSidebarListSuccess = (data) => { 13 | return { 14 | type: 'GET_SIDEBAR_LIST_SUCCESS', 15 | data 16 | } 17 | } 18 | 19 | export const toggleSidebar = () => ({ 20 | type: 'TOGGLE_SIDEBAR', 21 | }) 22 | 23 | export function getSidebarData (url, params,successFn=()=>{}) { 24 | return dispatch => { 25 | axiosGet(url, params, (data)=>{ 26 | dispatch(getSidebarListSuccess(data.data)) 27 | successFn() 28 | }) 29 | } 30 | } 31 | 32 | export const getContentList = () => { 33 | return { 34 | type: 'GET_CONTENT_LIST' 35 | } 36 | } 37 | 38 | export const getContentListSuccess = (data) => { 39 | return { 40 | type: 'GET_CONTENT_LIST_SUCCESS', 41 | data 42 | } 43 | } 44 | export function getContentData (url, params,successFn=()=>{}) { 45 | return dispatch => { 46 | axiosGet(url, params, (data)=>{ 47 | dispatch(getContentListSuccess(data.data)) 48 | successFn() 49 | }) 50 | } 51 | } 52 | export const getNextNewsBefore = () => { 53 | return { 54 | type: 'GET_NEXT_NEWS_BEFORE' 55 | } 56 | } 57 | 58 | export const getNextNewsSuccess = (data) => { 59 | return { 60 | type: 'GET_NEXT_NEWS_SUCCESS', 61 | data 62 | } 63 | } 64 | 65 | export function getNextNews (url, params,successFn=()=>{}) { 66 | return dispatch => { 67 | dispatch(getNextNewsBefore()) 68 | axiosGet(url, params, (data)=>{ 69 | dispatch(getNextNewsSuccess(data.data)) 70 | successFn() 71 | }) 72 | } 73 | } 74 | 75 | export function fetchData (url, params,successFn=()=>{}) { 76 | return dispatch => { 77 | dispatch(fetchDataStart()); 78 | axiosGet(url, params,( data )=>{ 79 | dispatch(fetchDataSuccess( data.data )); 80 | successFn(); 81 | }) 82 | } 83 | } 84 | 85 | function fetchDataStart() { 86 | return { 87 | type: 'FETCH_DATA_START' 88 | }; 89 | } 90 | function fetchDataSuccess(data) { 91 | return { 92 | type: 'FETCH_DATA_SUCCESS', 93 | data 94 | }; 95 | } 96 | function fetchNextDataSuccess(data) { 97 | return { 98 | type: 'FETCH_NEXT_DATA_SUCCESS', 99 | data 100 | }; 101 | } 102 | 103 | export function fetchNextData (url, params,successFn=()=>{}) { 104 | return dispatch => { 105 | dispatch(fetchDataStart()); 106 | axiosGet(url, params,( data )=>{ 107 | dispatch(fetchNextDataSuccess( data.data )); 108 | successFn(); 109 | }) 110 | } 111 | } 112 | 113 | export function fetchDataError(data) { 114 | return { 115 | type: 'FETCH_DATA_ERROR', 116 | data 117 | }; 118 | } 119 | 120 | export const showCollection = () => { 121 | return { 122 | type: 'SHOW_COLLECTION' 123 | } 124 | } 125 | 126 | export const hideCollection = () => { 127 | return { 128 | type: 'HIDE_COLLECTION' 129 | } 130 | } 131 | 132 | export const showShare = () => { 133 | return { 134 | type: 'SHOW_SHARE' 135 | } 136 | } 137 | 138 | export const hideShare = () => { 139 | return { 140 | type: 'HIDE_SHARE' 141 | } 142 | } 143 | 144 | export const showBox = () => { 145 | return { 146 | type: 'SHOW_BOX' 147 | } 148 | } 149 | 150 | export const hideBox = () => { 151 | return { 152 | type: 'HIDE_BOX' 153 | } 154 | } 155 | 156 | export const getThemeSuccess = (data) => { 157 | return { 158 | type: 'GET_THEME_SUCCESS', 159 | data 160 | } 161 | } 162 | export function getThemeData (url, params,successFn=()=>{}) { 163 | return dispatch => { 164 | axiosGet(url, params, (data)=>{ 165 | dispatch(getThemeSuccess(data.data)) 166 | successFn() 167 | }) 168 | } 169 | } 170 | export function getThemeBeforeData (url, params,successFn=()=>{}) { 171 | return dispatch => { 172 | dispatch(getNextNewsBefore()) 173 | axiosGet(url, params, (data)=>{ 174 | dispatch(getThemeBeforeSuccess(data.data)) 175 | successFn() 176 | }) 177 | } 178 | } 179 | 180 | export const getThemeBeforeSuccess = (data) => { 181 | return { 182 | type: 'GET_THEME_BEFORE_SUCCESS', 183 | data 184 | } 185 | } 186 | 187 | export const initDetailData = () => { 188 | return { 189 | type: 'INIT_DETAIL_DATA' 190 | } 191 | } 192 | 193 | export function getLongComments (url, params,successFn=()=>{}) { 194 | return dispatch => { 195 | dispatch(fetchDataStart()) 196 | axiosGet(url, params, (data)=>{ 197 | dispatch(getLongCommentsSuccess(data.data)) 198 | successFn() 199 | }) 200 | } 201 | } 202 | 203 | export const getLongCommentsSuccess = (data) => { 204 | return { 205 | type: 'GET_LONG_COMMENTS_SUCCESS', 206 | data 207 | } 208 | } 209 | 210 | 211 | export function getShortComments (url, params,successFn=()=>{}) { 212 | return dispatch => { 213 | dispatch(fetchDataStart()) 214 | axiosGet(url, params, (data)=>{ 215 | dispatch(getShortCommentsSuccess(data.data)) 216 | successFn() 217 | }) 218 | } 219 | } 220 | 221 | export const getShortCommentsSuccess = (data) => { 222 | return { 223 | type: 'GET_SHORT_COMMENTS_SUCCESS', 224 | data 225 | } 226 | } 227 | 228 | 229 | 230 | export function getShortCommentsNext (url, params,successFn=()=>{}) { 231 | return dispatch => { 232 | dispatch(fetchDataStart()) 233 | axiosGet(url, params, (data)=>{ 234 | dispatch(getShortCommentsNextSuccess(data.data)) 235 | successFn() 236 | }) 237 | } 238 | } 239 | 240 | export const getShortCommentsNextSuccess = (data) => { 241 | return { 242 | type: 'GET_SHORT_COMMENTS_NEXT_SUCCESS', 243 | data 244 | } 245 | } 246 | 247 | export const initComments = () => { 248 | return { 249 | type: 'INIT_COMMENTS' 250 | } 251 | } 252 | 253 | export const initSection = () => { 254 | return { 255 | type: 'INIT_SECTION' 256 | } 257 | } 258 | 259 | export function getSectionList (url, params,successFn=()=>{}) { 260 | return dispatch => { 261 | dispatch(getSectionStart()); 262 | axiosGet(url, params,( data )=>{ 263 | dispatch(getSectionSuccess( data.data )); 264 | successFn(); 265 | }) 266 | } 267 | } 268 | 269 | function getSectionStart() { 270 | return { 271 | type: 'GET_SECTION_START' 272 | }; 273 | } 274 | function getSectionSuccess(data) { 275 | return { 276 | type: 'GET_SECTION_SUCCESS', 277 | data 278 | }; 279 | } 280 | function getNextSectionSuccess(data) { 281 | return { 282 | type: 'GET_NEXT_SECTION_SUCCESS', 283 | data 284 | }; 285 | } 286 | 287 | export function getNextSection (url, params,successFn=()=>{}) { 288 | return dispatch => { 289 | dispatch(getSectionStart()); 290 | axiosGet(url, params,( data )=>{ 291 | dispatch(getNextSectionSuccess( data.data )); 292 | successFn(); 293 | }) 294 | } 295 | } 296 | 297 | export function getRecommender (url, params,successFn=()=>{}) { 298 | return dispatch => { 299 | axiosGet(url, params,( data )=>{ 300 | dispatch(getRecommenderSuccess( data.data )); 301 | successFn(); 302 | }) 303 | } 304 | } 305 | 306 | function getRecommenderSuccess(data) { 307 | return { 308 | type: 'GET_RECOMMENDER_SUCCESS', 309 | data 310 | }; 311 | } 312 | 313 | export const initRecommender = () => { 314 | return { 315 | type: 'INIT_RECOMMENDER' 316 | } 317 | } 318 | 319 | export const changeMode = () => { 320 | return { 321 | type: 'CHANGE_MODE' 322 | } 323 | } -------------------------------------------------------------------------------- /app/redux/reducer/comments.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/9. 3 | */ 4 | const initState = { 5 | long_comments: [], 6 | short_comments: [], 7 | loading: false, 8 | show_box: false 9 | } 10 | 11 | 12 | export const commentsData = (state = initState, action) => { 13 | switch (action.type) { 14 | case 'GET_LONG_COMMENTS_SUCCESS': 15 | return { 16 | ...state, 17 | long_comments: action.data.comments, 18 | loading: false 19 | } 20 | case 'GET_SHORT_COMMENTS_SUCCESS': 21 | return Object.assign({}, { 22 | ...state, 23 | short_comments: action.data.comments, 24 | loading: false, 25 | id: action.data.comments[action.data.comments.length - 1].id 26 | }) 27 | case 'GET_SHORT_COMMENTS_NEXT_SUCCESS': 28 | return Object.assign({}, { 29 | ...state, 30 | loading: false, 31 | short_comments: state.short_comments.concat(action.data.comments), 32 | id: action.data.comments[action.data.comments.length - 1].id 33 | }) 34 | case 'FETCH_DATA_START': 35 | return Object.assign({}, { 36 | ...state, 37 | loading: true 38 | }) 39 | case 'SHOW_BOX': 40 | return Object.assign({}, { 41 | ...state, 42 | show_box: true 43 | }) 44 | case 'HIDE_BOX': 45 | return Object.assign({}, { 46 | ...state, 47 | show_box: false 48 | }) 49 | case 'INIT_COMMENTS': 50 | return Object.assign({}, initState) 51 | default: 52 | return state 53 | } 54 | } -------------------------------------------------------------------------------- /app/redux/reducer/detail.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by miaoyicheng on 2017/2/14. 3 | */ 4 | 5 | const initState = { 6 | body: '', 7 | image_source: '', 8 | loading: false, 9 | title: '', 10 | image: '', 11 | collection: false, 12 | show_share: false, 13 | section: { 14 | name: '' 15 | } 16 | } 17 | 18 | export const detailContent = (state = initState, action) => { 19 | switch (action.type) { 20 | case 'FETCH_DATA_SUCCESS': 21 | return Object.assign({}, state, action.data, {loading: false}) 22 | case 'FETCH_DATA_START': 23 | return { 24 | ...state, 25 | loading: true 26 | } 27 | case 'SHOW_COLLECTION': 28 | return { 29 | ...state, 30 | collection: true 31 | } 32 | case 'HIDE_COLLECTION': 33 | return { 34 | ...state, 35 | collection: false 36 | } 37 | case 'SHOW_SHARE': 38 | return { 39 | ...state, 40 | show_share: true 41 | } 42 | case 'HIDE_SHARE': 43 | return { 44 | ...state, 45 | show_share: false 46 | } 47 | case 'INIT_DETAIL_DATA': 48 | return Object.assign({}, initState) 49 | // case 'TOGGLE_SIDEBAR': 50 | // return Object.assign({}, state, { 51 | // ...state, 52 | // active: !state.active 53 | // }) 54 | default: 55 | return state 56 | } 57 | } -------------------------------------------------------------------------------- /app/redux/reducer/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/9. 3 | */ 4 | import { combineReducers } from 'redux'; 5 | import { sidebarList }from './sidebar'; 6 | import { contentList }from './list'; 7 | import { detailContent }from './detail'; 8 | import { commentsData }from './comments'; 9 | import { sectionList }from './section'; 10 | import { recommenderData }from './recommender'; 11 | 12 | const zhdata = combineReducers({ 13 | sidebar: sidebarList, 14 | content_list: contentList, 15 | detail_content: detailContent, 16 | comments_data: commentsData, 17 | section_list: sectionList, 18 | recommender_data: recommenderData 19 | }) 20 | 21 | export default zhdata; 22 | -------------------------------------------------------------------------------- /app/redux/reducer/list.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/15. 3 | */ 4 | const initState = { 5 | loading: false, 6 | date: '', 7 | all_stories: [], 8 | top_stories: [], 9 | theme_stories: { 10 | stories: [], 11 | background: '', 12 | editors: [] 13 | }, 14 | night_style: false 15 | } 16 | 17 | 18 | export const contentList = (state = initState, action) => { 19 | switch (action.type) { 20 | case 'CHANGE_MODE': 21 | return Object.assign({}, state, { 22 | ...state, 23 | night_style: !state.night_style 24 | }) 25 | case 'GET_CONTENT_LIST': 26 | case 'GET_CONTENT_LIST_SUCCESS': 27 | return Object.assign({}, state, { 28 | all_stories: [].concat(action.data), 29 | top_stories: action.data.top_stories, 30 | date: action.data.date, 31 | loading: false 32 | }) 33 | case 'GET_NEXT_NEWS_BEFORE': 34 | return Object.assign({}, state, { 35 | ...state, 36 | loading: true 37 | }) 38 | case 'GET_NEXT_NEWS_SUCCESS': 39 | return Object.assign({}, state, { 40 | ...state, 41 | loading: false, 42 | date: action.data.date, 43 | all_stories: state.all_stories.concat(action.data) 44 | }) 45 | case 'GET_THEME_SUCCESS': 46 | return Object.assign({}, state, { 47 | ...state, 48 | loading: false, 49 | theme_stories: action.data 50 | }) 51 | case 'GET_THEME_BEFORE_SUCCESS': 52 | return Object.assign({}, state, { 53 | ...state, 54 | loading: false, 55 | theme_stories: { 56 | ...state.theme_stories, 57 | stories: state.theme_stories.stories.concat(action.data.stories) 58 | } 59 | }) 60 | default: 61 | return state 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/redux/reducer/recommender.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/9. 3 | */ 4 | const initState = { 5 | items: [{ 6 | recommenders: [] 7 | }], 8 | editors: [] 9 | } 10 | 11 | export const recommenderData = (state = initState, action) => { 12 | switch (action.type) { 13 | case 'GET_RECOMMENDER_SUCCESS': 14 | return Object.assign({}, action.data) 15 | case 'INIT_RECOMMENDER': 16 | return Object.assign({}, initState) 17 | default: 18 | return state 19 | } 20 | } -------------------------------------------------------------------------------- /app/redux/reducer/section.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/9. 3 | */ 4 | const initState = { 5 | stories: [], 6 | loading: false, 7 | name: '', 8 | timestamp: '' 9 | } 10 | 11 | 12 | export const sectionList = (state = initState, action) => { 13 | switch (action.type) { 14 | case 'GET_SECTION_START': 15 | return Object.assign({}, { 16 | ...state, 17 | loading: true 18 | }) 19 | case 'GET_SECTION_SUCCESS': 20 | return Object.assign({}, action.data, { 21 | loading: false 22 | }) 23 | case 'GET_NEXT_SECTION_SUCCESS': 24 | return Object.assign({}, state, { 25 | stories: state.stories.concat(action.data.stories), 26 | timestamp: action.data.timestamp, 27 | loading: false 28 | }) 29 | case 'INIT_SECTION': 30 | return Object.assign({}, initState) 31 | default: 32 | return state 33 | } 34 | } -------------------------------------------------------------------------------- /app/redux/reducer/sidebar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/9. 3 | */ 4 | const initState = { 5 | list: [], 6 | active: false 7 | } 8 | 9 | 10 | export const sidebarList = (state = initState, action) => { 11 | switch (action.type) { 12 | case 'GET_SIDEBAR_LIST': 13 | return { 14 | list: action.data.others 15 | } 16 | case 'GET_SIDEBAR_LIST_SUCCESS': 17 | return { 18 | list: action.data.others, 19 | active: false 20 | } 21 | case 'TOGGLE_SIDEBAR': 22 | return Object.assign({}, state, { 23 | ...state, 24 | active: !state.active 25 | }) 26 | default: 27 | return state 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /app/router/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/11/21. 3 | */ 4 | 5 | 6 | export default ( 7 |
    8 | {dispatch(resetState())}}/> 9 | 10 |
    11 | ); 12 | -------------------------------------------------------------------------------- /app/util/ajax.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/12. 3 | */ 4 | 5 | import 'axios' 6 | 7 | export const axiosGet = (url, params = {}, sucFn=()=>{}, failFn=()=>{}) => { 8 | axios.get(url, params) 9 | .then( (res) => { 10 | sucFn(res) 11 | }) 12 | .catch((error) =>{ 13 | failFn(error) 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /app/util/filter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/12/16. 3 | */ 4 | /** 5 | * 替换url 6 | * srcUrl 初始url 7 | * 8 | */ 9 | exports.replaceUrl = (srcUrl) => { 10 | return srcUrl.replace(/http\w{0,1}:\/\/p/g, 'https://images.weserv.nl/?url=p') 11 | } 12 | 13 | /** 14 | * 字符串截取 15 | * '201604059' | subStr 4 => 2016 16 | * '201604059' | subStr -4 => 4059 17 | */ 18 | exports.subStr = (str, number) => { 19 | if (!str) return '' 20 | 21 | if (number < 0) { 22 | return str.substr(str.length + number) 23 | } else { 24 | return str.substr(0, number) 25 | } 26 | } 27 | 28 | /** 29 | * 格式化时间戳 30 | * 1461658688000 | formatTime "yyyy-MM-dd hh:mm:ss" 31 | */ 32 | exports.formatTime = (timeStamp, fmt) => { // author: meizz 33 | if (!timeStamp) { 34 | return '' 35 | } 36 | var _timeStamp = parseInt(timeStamp) 37 | if (_timeStamp.toString().length === 10) { 38 | _timeStamp *= 1000 39 | } 40 | !fmt && (fmt = 'yyyy-MM-dd') 41 | 42 | var t = new Date(_timeStamp) 43 | 44 | var o = { 45 | 'M+': t.getMonth() + 1, // 月份 46 | 'd+': t.getDate(), // 日 47 | 'h+': t.getHours(), // 小时 48 | 'm+': t.getMinutes(), // 分 49 | 's+': t.getSeconds(), // 秒 50 | 'q+': Math.floor((t.getMonth() + 3) / 3), // 季度 51 | 'S': t.getMilliseconds() // 毫秒 52 | } 53 | if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (t.getFullYear() + '').substr(4 - RegExp.$1.length)) 54 | for (var k in o) { 55 | if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))) 56 | } 57 | return fmt 58 | } 59 | 60 | /** 61 | * 把4位数转换成K 62 | * 63 | * 64 | */ 65 | exports.toK = (str) => { 66 | if (str > 999) { 67 | let item = (str / 1000) + '' 68 | return item.substring(0, item.length - 2) + 'K' 69 | } else { 70 | return str 71 | } 72 | } 73 | 74 | /** 75 | * 把日期格式化再加上星期判断 76 | * 77 | */ 78 | 79 | exports.dateTime = (str) => { 80 | // 根据手机判断的时间 81 | let fmt = 'yyyyMMdd' 82 | var t = new Date() 83 | var o = { 84 | 'M+': t.getMonth() + 1, // 月份 85 | 'd+': t.getDate(), // 日 86 | 'h+': t.getHours(), // 小时 87 | 'm+': t.getMinutes(), // 分 88 | 's+': t.getSeconds(), // 秒 89 | 'q+': Math.floor((t.getMonth() + 3) / 3), // 季度 90 | 'S': t.getMilliseconds() // 毫秒 91 | } 92 | if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (t.getFullYear() + '').substr(4 - RegExp.$1.length)) 93 | for (var k in o) { 94 | if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))) 95 | } 96 | // 根据接口判断的时间 97 | let year = str.slice(0, 4) 98 | let month = str.slice(4, 6) 99 | let day = str.slice(6, 8) 100 | let dateArr = [year, month, day] 101 | let date = dateArr.join('/') 102 | let index = new Date(date).getDay() 103 | let week = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'][index] 104 | 105 | // 判断后返回字段 106 | let dt = dateArr.join('') 107 | if (dt === fmt) { 108 | return '今日热闻' 109 | } else { 110 | return month + '月' + day + '日 ' + week 111 | } 112 | } 113 | 114 | /** 115 | * 隐藏手机中间四位 116 | * 117 | */ 118 | exports.formatPhone = (phone) => { 119 | if (typeof phone == 'number') { 120 | phone = phone.toString(); 121 | } 122 | return phone.substr(0, 3) + '****' + phone.substr(7, 11); 123 | } 124 | -------------------------------------------------------------------------------- /app/view/author.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import '../css/author.scss' 3 | 4 | const author = React.createClass({ 5 | render() { 6 | return ( 7 |
    8 |
    9 | 10 |
    11 |

    yatessss

    12 | 18 |
    19 |

    登出

    20 |
    21 |
    22 | ) 23 | } 24 | }) 25 | 26 | export default author -------------------------------------------------------------------------------- /app/view/comments.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {getLongComments, getShortComments, getShortCommentsNext, showBox, hideBox, initComments} from '../redux/action' 3 | import { connect } from 'react-redux' 4 | import api from '../api' 5 | import '../css/comments.scss' 6 | import CommentsItem from '../components/comment-item.jsx' 7 | 8 | const comments = React.createClass({ 9 | componentWillMount () { 10 | let id = this.props.params.id 11 | let {dispatch} = this.props 12 | dispatch(getLongComments(`${api.GET_COMMENTS}${id}/long-comments`)) 13 | window.addEventListener('scroll', this.getScrollData, false) 14 | }, 15 | goBack () { 16 | window.history.back() 17 | }, 18 | getShortComments() { 19 | let {dispatch} = this.props 20 | let id = this.props.params.id 21 | dispatch(getShortComments(`${api.GET_COMMENTS}${id}/short-comments`)) 22 | }, 23 | getScrollData () { 24 | let {data} = this.props 25 | if ((window.document.body.offsetHeight + window.document.body.scrollTop) + 100 > window.document.body.scrollHeight && !data.loading) { 26 | this.getShortCommentsNext() 27 | } 28 | }, 29 | getShortCommentsNext () { 30 | let {dispatch, data} = this.props 31 | let id = this.props.params.id 32 | dispatch(getShortCommentsNext(`${api.GET_COMMENTS}${id}/short-comments/before/${data.id}`)) 33 | }, 34 | componentWillUnmount () { 35 | window.removeEventListener('scroll', this.getScrollData, false) 36 | let {dispatch} = this.props 37 | dispatch(initComments()) 38 | }, 39 | render() { 40 | let extra = JSON.parse(window.sessionStorage.extra) 41 | let {data} = this.props 42 | let {dispatch} = this.props 43 | console.log(this.props) 44 | return ( 45 |
    46 |
    47 |
    48 |

    {extra.comments} 条点评

    49 |
    50 |
    51 | 70 | 71 | 72 | 78 | {/**/} 79 | {(()=>{ 80 | if (data.show_box) { 81 | return ( 82 |
    {dispatch(hideBox())}}> 83 |
    84 |

    赞同

    85 |

    举报

    86 |

    复制

    87 |

    回复

    88 |
    89 |
    90 | ) 91 | } 92 | })()} 93 |
    94 | ) 95 | } 96 | }) 97 | 98 | export default connect((state)=>{ 99 | return { 100 | data: state.comments_data 101 | }; 102 | })(comments); -------------------------------------------------------------------------------- /app/view/detail.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import DetailHeader from '../components/detail-header.jsx' 3 | import DetailContent from '../components/detail-content.jsx' 4 | import { connect } from 'react-redux' 5 | 6 | const detail = React.createClass({ 7 | render() { 8 | let id = this.props.params.id 9 | return ( 10 |
    11 | 12 | 13 | {this.props.children} 14 |
    15 | ) 16 | } 17 | }) 18 | 19 | export default detail 20 | -------------------------------------------------------------------------------- /app/view/editor.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import CommonHeader from '../components/common-header.jsx' 3 | import DetailContent from '../components/detail-content.jsx' 4 | import { connect } from 'react-redux' 5 | import filter from '../util/filter' 6 | import '../css/editor.scss' 7 | 8 | const editor = React.createClass({ 9 | componentWillMount () { 10 | }, 11 | render() { 12 | console.log(this.props) 13 | let editor = JSON.parse(window.sessionStorage.editors) 14 | return ( 15 |
    16 | 17 | 32 |
    33 | ) 34 | } 35 | }) 36 | 37 | export default connect((state)=>{ 38 | return { 39 | editor: state.content_list.theme_stories.editors 40 | }; 41 | })(editor); -------------------------------------------------------------------------------- /app/view/list.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import SideBar from '../components/sidebar.jsx' 3 | import ListHeader from '../components/list-header.jsx' 4 | 5 | const list = React.createClass({ 6 | componentDidUpdate () { 7 | }, 8 | iconDisplay () { 9 | if (this.props.params.id) { 10 | return false 11 | } else { 12 | return true 13 | } 14 | }, 15 | title () { 16 | switch (this.props.params.id) { 17 | case '13': 18 | return '日常心理学' 19 | case '12': 20 | return '用户推荐日报' 21 | case '3': 22 | return '电影日报' 23 | case '11': 24 | return '不许无聊' 25 | case '4': 26 | return '设计日报' 27 | case '5': 28 | return '大公司日报' 29 | case '6': 30 | return '财经日报' 31 | case '10': 32 | return '互联网安全' 33 | case '2': 34 | return '开始游戏' 35 | case '7': 36 | return '音乐日报' 37 | case '9': 38 | return '动漫日报' 39 | case '8': 40 | return '体育日报' 41 | default: 42 | return '首页' 43 | } 44 | }, 45 | render() { 46 | return ( 47 |
    48 | 49 | 50 | {this.props.children} 51 |
    52 | ) 53 | } 54 | }) 55 | export default list 56 | -------------------------------------------------------------------------------- /app/view/recommender.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import CommonHeader from '../components/common-header.jsx' 3 | import { connect } from 'react-redux' 4 | import filter from '../util/filter' 5 | import '../css/recommender.scss' 6 | import {getRecommender, initRecommender} from '../redux/action' 7 | import api from '../api' 8 | 9 | 10 | const recommender = React.createClass({ 11 | componentWillMount () { 12 | let {dispatch} = this.props 13 | dispatch(getRecommender(api.GET_COMMENTS + this.props.params.id + '/recommenders')) 14 | }, 15 | componentWillUnmount () { 16 | let {dispatch} = this.props 17 | dispatch(initRecommender()) 18 | }, 19 | render() { 20 | let {recommender} = this.props 21 | return ( 22 |
    23 | 24 | 67 |
    68 | ) 69 | } 70 | }) 71 | 72 | export default connect((state)=>{ 73 | return { 74 | recommender: state.recommender_data 75 | }; 76 | })(recommender); -------------------------------------------------------------------------------- /app/view/section.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ListHeader from '../components/common-header.jsx' 3 | import ListItem from '../components/list-item.jsx' 4 | import api from '../api' 5 | import '../css/section.scss' 6 | import { connect } from 'react-redux' 7 | import { getSectionList, initSection, getNextSection } from '../redux/action' 8 | 9 | const section = React.createClass({ 10 | componentWillMount () { 11 | let { dispatch} = this.props 12 | dispatch(getSectionList(api.GET_SECTION + this.props.params.id)) 13 | window.addEventListener('scroll', this.getScrollData, false) 14 | }, 15 | getScrollData () { 16 | let {section} = this.props 17 | if ((window.document.body.offsetHeight + window.document.body.scrollTop) + 100 > window.document.body.scrollHeight && !section.loading) { 18 | this.getSectionNext() 19 | } 20 | }, 21 | getSectionNext () { 22 | let {dispatch, section} = this.props 23 | let id = this.props.params.id 24 | dispatch(getNextSection(`${api.GET_SECTION}${id}/before/${section.timestamp}`)) 25 | }, 26 | componentWillUnmount () { 27 | let {dispatch} = this.props 28 | window.removeEventListener('scroll', this.getScrollData, false) 29 | dispatch(initSection()) 30 | }, 31 | render() { 32 | let {section} = this.props 33 | return ( 34 |
    35 | {/**/} 36 | 37 | 38 | 43 |
    44 | ) 45 | } 46 | }) 47 | const mapStateToProps = (state, ownProps) => ({ 48 | section: state.section_list 49 | }) 50 | export default connect( 51 | mapStateToProps, 52 | // mapDispatchToProps 53 | )(section) -------------------------------------------------------------------------------- /build/CNAME: -------------------------------------------------------------------------------- 1 | zhihudaily-react.yatessss.com -------------------------------------------------------------------------------- /build/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 知乎日报 8 | 9 | 10 |
    11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /build/vendors.js: -------------------------------------------------------------------------------- 1 | !function(e){function t(e){var t=document.getElementsByTagName("head")[0],n=document.createElement("script");n.type="text/javascript",n.charset="utf-8",n.src=p.p+""+e+"."+E+".hot-update.js",t.appendChild(n)}function n(e){if("undefined"==typeof XMLHttpRequest)return e(new Error("No browser support"));try{var t=new XMLHttpRequest,n=p.p+""+E+".hot-update.json";t.open("GET",n,!0),t.timeout=1e4,t.send(null)}catch(t){return e(t)}t.onreadystatechange=function(){if(4===t.readyState)if(0===t.status)e(new Error("Manifest request to "+n+" timed out."));else if(404===t.status)e();else if(200!==t.status&&304!==t.status)e(new Error("Manifest request to "+n+" failed."));else{try{var r=JSON.parse(t.responseText)}catch(t){return void e(t)}e(null,r)}}}function r(e){function t(e,t){"ready"===P&&i("prepare"),A++,p.e(e,function(){function n(){A--,"prepare"===P&&(j[e]||s(e),0===A&&0===O&&l())}try{t.call(null,r)}finally{n()}})}var n=k[e];if(!n)return p;var r=function(t){return n.hot.active?k[t]?(k[t].parents.indexOf(e)<0&&k[t].parents.push(e),n.children.indexOf(t)<0&&n.children.push(t)):_=[e]:(console.warn("[HMR] unexpected require("+t+") from disposed module "+e),_=[]),p(t)};for(var o in p)Object.prototype.hasOwnProperty.call(p,o)&&(v?Object.defineProperty(r,o,function(e){return{configurable:!0,enumerable:!0,get:function(){return p[e]},set:function(t){p[e]=t}}}(o)):r[o]=p[o]);return v?Object.defineProperty(r,"e",{enumerable:!0,value:t}):r.e=t,r}function o(e){var t={_acceptedDependencies:{},_declinedDependencies:{},_selfAccepted:!1,_selfDeclined:!1,_disposeHandlers:[],active:!0,accept:function(e,n){if("undefined"==typeof e)t._selfAccepted=!0;else if("function"==typeof e)t._selfAccepted=e;else if("object"==typeof e)for(var r=0;r=0&&t._disposeHandlers.splice(n,1)},check:u,apply:f,status:function(e){return e?void w.push(e):P},addStatusHandler:function(e){w.push(e)},removeStatusHandler:function(e){var t=w.indexOf(e);t>=0&&w.splice(t,1)},data:x[e]};return t}function i(e){P=e;for(var t=0;t0;){var i=r.pop(),e=k[i];if(e&&!e.hot._selfAccepted){if(e.hot._selfDeclined)return new Error("Aborted because of self decline: "+i);if(0===i)return;for(var a=0;a=0||(c.hot._acceptedDependencies[i]?(n[u]||(n[u]=[]),o(n[u],[i])):(delete n[u],t.push(u),r.push(u)))}}}return[t,n]}function o(e,t){for(var n=0;n0;){var f=y.pop(),g=k[f];if(g){for(var w={},O=g.hot._disposeHandlers,A=0;A=0&&N.parents.splice(D,1)}}}}for(var f in u)if(Object.prototype.hasOwnProperty.call(u,f))for(var g=k[f],I=u[f],A=0;A=0&&g.children.splice(D,1)}i("apply"),E=b;for(var f in s)Object.prototype.hasOwnProperty.call(s,f)&&(e[f]=s[f]);var R=null;for(var f in u)if(Object.prototype.hasOwnProperty.call(u,f)){for(var g=k[f],I=u[f],M=[],v=0;v=0||M.push(j)}for(var v=0;v1){for(var y=Array(v),m=0;m1){for(var g=Array(b),E=0;E>"),j={array:a("array"),bool:a("boolean"),func:a("function"),number:a("number"),object:a("object"),string:a("string"),symbol:a("symbol"),any:u(),arrayOf:c,element:s(),instanceOf:l,node:h(),objectOf:p,oneOf:f,oneOfType:d,shape:v};o.prototype=Error.prototype,e.exports=j},function(e,t){"use strict";var n="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";e.exports=n},function(e,t){"use strict";e.exports="15.4.2"},function(e,t,n){"use strict";function r(e){return i.isValidElement(e)?void 0:o("143"),e}var o=n(7),i=n(9);n(8);e.exports=r}]); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zhihudaily-react-2", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "build": "NODE_ENV=production webpack", 8 | "dev": "NODE_ENV=dev webpack-dev-server --devtool eval --progress --colors --hot --content-base build" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "autoprefixer": "^6.5.3", 14 | "babel-loader": "^6.2.7", 15 | "babel-preset-es2015": "^6.18.0", 16 | "babel-preset-react": "^6.16.0", 17 | "babel-preset-react-hmre": "^1.1.1", 18 | "babel-preset-stage-2": "^6.18.0", 19 | "css-loader": "^0.26.0", 20 | "file-loader": "^0.9.0", 21 | "node-sass": "^3.13.0", 22 | "postcss-loader": "^1.1.1", 23 | "postcss-px2rem": "^0.3.0", 24 | "react-pure-render": "^1.0.2", 25 | "react-slick": "^0.14.6", 26 | "sass-loader": "^4.0.2", 27 | "slick-carousel": "^1.6.0", 28 | "style-loader": "^0.13.1", 29 | "url-loader": "^0.5.7", 30 | "webpack": "^1.13.3" 31 | }, 32 | "dependencies": { 33 | "axios": "^0.15.2", 34 | "babel-core": "^6.18.2", 35 | "lib-flexible": "^0.3.2", 36 | "react": "^15.4.0", 37 | "react-dom": "^15.4.0", 38 | "react-redux": "^4.4.6", 39 | "react-router": "^3.0.0", 40 | "redux": "^3.6.0", 41 | "redux-devtools": "^3.3.1", 42 | "redux-devtools-dock-monitor": "^1.1.1", 43 | "redux-devtools-log-monitor": "^1.0.11", 44 | "redux-thunk": "^2.1.0", 45 | "swiper": "^3.4.1", 46 | "webpack-dev-server": "^1.16.2" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yatessss on 16/11/18. 3 | */ 4 | var path = require('path'); 5 | var webpack = require('webpack'); 6 | var nodeEnv 7 | 8 | console.log(process.env.NODE_ENV) 9 | 10 | if (process.env.NODE_ENV === 'dev') { 11 | nodeEnv = { 12 | app: './app/main.dev.js', 13 | vendors: ['react'] 14 | } 15 | } else { 16 | nodeEnv = { 17 | app: './app/main.js', 18 | vendors: ['react'] 19 | } 20 | } 21 | 22 | var config = { 23 | entry: nodeEnv, 24 | output: { 25 | path: path.resolve(__dirname, 'build'), 26 | filename: 'app.js' 27 | }, 28 | module: { 29 | loaders: [{ 30 | test: /\.jsx?$/, 31 | loader: 'babel', 32 | exclude: /node_modules/ 33 | }, { 34 | test: /\.css$/, // Only .css files 35 | loader: "style-loader!css-loader!postcss-loader" 36 | }, { 37 | test: /\.scss$/, 38 | loader: 'style!css!postcss-loader!sass' 39 | }, { 40 | test: /\.(png|jpg)$/, 41 | loader: 'url?limit=25000' 42 | }, { 43 | test: /\.woff$/, 44 | loader: 'url?limit=100000' 45 | }] 46 | }, 47 | postcss: [require('postcss-px2rem')({ 48 | baseDpr: 1, // base device pixel ratio (default: 2) 49 | threeVersion: false, // whether to generate @1x, @2x and @3x version (default: false) 50 | remVersion: true, // whether to generate rem version (default: true) 51 | remUnit: 37.5, // rem unit value (default: 75) 52 | remPrecision: 3 // rem precision (default: 6) 53 | })], 54 | autoprefixer: { 55 | browsers: ["Android >= 2.3", "iOS >= 4"], //, "ChromeAndroid > 1%" 56 | cascade: false // 不美化输出 css 57 | }, 58 | devServer: { 59 | inline: true 60 | }, 61 | plugins: [ 62 | new webpack.HotModuleReplacementPlugin(), 63 | new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js', Infinity), 64 | // new webpack.DefinePlugin({ 65 | // 'process.env': { 66 | // NODE_ENV: JSON.stringify('production') 67 | // } 68 | // }), 69 | new webpack.optimize.UglifyJsPlugin({ 70 | compress: { 71 | warnings: false 72 | } 73 | }) 74 | ] 75 | }; 76 | 77 | module.exports = config; 78 | 79 | --------------------------------------------------------------------------------