aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package.json4
-rw-r--r--src/web/js/components/MainApp.react.js13
-rw-r--r--src/web/js/components/Menu.react.js148
-rw-r--r--src/web/js/components/MiddlePanel.react.js24
-rw-r--r--src/web/templates/home2.html103
5 files changed, 199 insertions, 93 deletions
diff --git a/package.json b/package.json
index ba072568..64569b63 100644
--- a/package.json
+++ b/package.json
@@ -11,9 +11,9 @@
"jquery": "^2.2.0",
"keymirror": "~0.1.0",
"object-assign": "^1.0.0",
- "react": "^0.14.0",
+ "react": "^0.14.6",
"react-bootstrap": "^0.14.1",
- "react-dom": "^0.14.0"
+ "react-dom": "^0.14.6"
},
"devDependencies": {
"browserify": "^6.2.0",
diff --git a/src/web/js/components/MainApp.react.js b/src/web/js/components/MainApp.react.js
index bd643be1..816e8c82 100644
--- a/src/web/js/components/MainApp.react.js
+++ b/src/web/js/components/MainApp.react.js
@@ -1,6 +1,6 @@
var React = require('react');
-var Col = require('react-bootstrap/lib/Col');
-var Grid = require('react-bootstrap/lib/Grid');
+var Col = require('react-bootstrap/Col');
+var Row = require('react-bootstrap/Row');
var Menu = require('./Menu.react');
var MiddlePanel = require('./MiddlePanel.react');
@@ -9,11 +9,8 @@ var RightPanel = require('./RightPanel.react');
var MainApp = React.createClass({
render: function() {
- return (<Grid fluid>
- <Col xsHidden smHidden md={3} lg={2}>
- <Menu.MenuFilter />
- <Menu.Menu />
- </Col>
+ return (<Row>
+ <Menu />
<Col xs={2} sm={2} md={4} lg={4}>
<MiddlePanel.MiddlePanelFilter />
<MiddlePanel.MiddlePanel />
@@ -22,7 +19,7 @@ var MainApp = React.createClass({
<RightPanel.RightPanelMenu />
<RightPanel.RightPanel />
</Col>
- </Grid>
+ </Row>
);
},
});
diff --git a/src/web/js/components/Menu.react.js b/src/web/js/components/Menu.react.js
index becc7a2e..4b8c167c 100644
--- a/src/web/js/components/Menu.react.js
+++ b/src/web/js/components/Menu.react.js
@@ -1,11 +1,9 @@
var React = require('react');
-var Row = require('react-bootstrap/lib/Row');
-var Badge = require('react-bootstrap/lib/Badge');
-var Button = require('react-bootstrap/lib/Button');
-var ButtonGroup = require('react-bootstrap/lib/ButtonGroup');
-var ListGroup = require('react-bootstrap/lib/ListGroup');
-var ListGroupItem = require('react-bootstrap/lib/ListGroupItem');
-var Glyphicon = require('react-bootstrap/lib/Glyphicon');
+var Col = require('react-bootstrap/Col');
+var Badge = require('react-bootstrap/Badge');
+var Button = require('react-bootstrap/Button');
+var ButtonGroup = require('react-bootstrap/ButtonGroup');
+var Glyphicon = require('react-bootstrap/Glyphicon');
var MenuStore = require('../stores/MenuStore');
var MenuActions = require('../actions/MenuActions');
@@ -36,10 +34,9 @@ var FeedItem = React.createClass({
} else if(this.props.error_count > 3) {
style = "warning";
}
- return (<ListGroupItem onMouseDown={this.handleClick} bsStyle={style}
- href="#" active={this.props.active}>
+ return (<li onClick={this.handleClick}>
{icon}{this.props.title}{badge_unread}
- </ListGroupItem>
+ </li>
);
},
handleClick: function() {
@@ -48,6 +45,34 @@ var FeedItem = React.createClass({
});
var Category = React.createClass({
+ propTypes: {category_id: React.PropTypes.number.isRequired,
+ filter: React.PropTypes.string.isRequired,
+ active_type: React.PropTypes.string,
+ active_id: React.PropTypes.number},
+ render: function() {
+ if(this.props.active_type == 'active_id'
+ && this.props.active_id == this.props.category_id) {
+ var classes = "success active";
+ } else {
+ var classes = "success";
+ }
+ return (<li className={classes}>
+ <h4 onClick={this.handleClick}>
+ {this.props.children}
+ </h4>
+ </li>
+ );
+ },
+ handleClick: function() {
+ if(this.props.category_id != null) {
+ MiddlePanelActions.setCategoryFilter(this.props.category_id);
+ } else {
+ MiddlePanelActions.removeParentFilter();
+ }
+ },
+});
+
+var CategoryGroup = React.createClass({
propTypes: {cat_id: React.PropTypes.number.isRequired,
filter: React.PropTypes.string.isRequired,
active_type: React.PropTypes.string,
@@ -89,19 +114,18 @@ var Category = React.createClass({
if(this.props.unread){
unread = <Badge pullRight>{this.props.unread}</Badge>;
}
- var active = a_type == 'category_id' && a_id == this.props.cat_id;
var ctrl = (<Glyphicon onMouseDown={this.toggleFolding} pullLeft
glyph={this.state.unfolded?"menu-down":"menu-right"} />
);
- return (<ListGroup>
- <ListGroupItem href="#" bsStyle="success"
- active={active}
- onMouseDown={this.handleClick}>
+ return (<ul className="nav nav-sidebar">
+ <Category category_id={this.props.cat_id}
+ active_type={this.props.active_id}
+ active_type={this.props.active_type}>
{ctrl} <strong>{this.props.name}</strong> {unread}
- </ListGroupItem>
+ </Category>
{feeds}
- </ListGroup>
+ </ul>
);
},
handleClick: function() {
@@ -114,43 +138,27 @@ var Category = React.createClass({
});
var MenuFilter = React.createClass({
- getInitialState: function() {
- return {filter: 'all', feed_in_error: false};
- },
+ propTypes: {feed_in_error: React.PropTypes.bool,
+ filter: React.PropTypes.string.isRequired},
render: function() {
var error_button = null;
- if (this.state.feed_in_error) {
- error_button = (<Button active={this.state.filter == "error"}
- onMouseDown={() => this.setFilter("error")}
+ if (this.props.feed_in_error) {
+ error_button = (<Button active={this.props.filter == "error"}
+ onMouseDown={() => MenuActions.setFilter("error")}
bsSize="small" bsStyle="warning">Error</Button>
);
}
- return (<Row className="show-grid">
- <ButtonGroup>
- <Button active={this.state.filter == "all"}
- onMouseDown={() => this.setFilter("all")}
- bsSize="small">All</Button>
- <Button active={this.state.filter == "unread"}
- onMouseDown={() => this.setFilter("unread")}
- bsSize="small">Unread</Button>
- {error_button}
- </ButtonGroup>
- </Row>
+ return (<ButtonGroup className="nav nav-sidebar">
+ <Button active={this.props.filter == "all"}
+ onMouseDown={() => MenuActions.setFilter("all")}
+ bsSize="small">All</Button>
+ <Button active={this.props.filter == "unread"}
+ onMouseDown={() => MenuActions.setFilter("unread")}
+ bsSize="small">Unread</Button>
+ {error_button}
+ </ButtonGroup>
);
},
- setFilter: function(filter) {
- this.setState({filter: filter});
- MenuActions.setFilter(filter);
- },
- componentDidMount: function() {
- MenuStore.addChangeListener(this._onChange);
- },
- componentWillUnmount: function() {
- MenuStore.removeChangeListener(this._onChange);
- },
- _onChange: function() {
- this.setState({feed_in_error: MenuStore._datas.feed_in_error});
- },
});
var Menu = React.createClass({
@@ -160,25 +168,36 @@ var Menu = React.createClass({
},
render: function() {
var state = this.state;
- var rmPrntFilt = (<ListGroupItem href="#" bsStyle="success"
- active={this.state.active_type == null
- || this.state.active_id == null}
- onMouseDown={MiddlePanelActions.removeParentFilter}
- header="All"></ListGroupItem>);
+ if (this.state.active_type == null || this.state.active_id == null) {
+ var all_classname = "success active";
+ } else {
+ var all_classname = "success";
+ }
+ var rmPrntFilt = (
+ <ul className="nav nav-sidebar">
+ <Category category_id={null}
+ active_type={this.props.active_id}
+ active_type={this.props.active_type}>
+ <strong>All</strong>
+ </Category>
+ </ul>
+ );
- return (<Row className="show-grid">
- <ListGroup>{rmPrntFilt}</ListGroup>
+ return (<Col xsHidden smHidden md={3} lg={2} className="show-grid sidebar">
+ <MenuFilter filter={this.state.filter}
+ feed_in_error={this.state.feed_in_error} />
+ {rmPrntFilt}
{this.state.categories.map(function(category){
- return (<Category key={"c" + category.id}
- filter={state.filter}
- active_type={state.active_type}
- active_id={state.active_id}
- cat_id={category.id}
- feeds={category.feeds}
- name={category.name}
- unread={category.unread} />);
+ return (<CategoryGroup key={"c" + category.id}
+ filter={state.filter}
+ active_type={state.active_type}
+ active_id={state.active_id}
+ cat_id={category.id}
+ feeds={category.feeds}
+ name={category.name}
+ unread={category.unread} />);
})}
- </Row>
+ </Col>
);
},
componentDidMount: function() {
@@ -194,8 +213,9 @@ var Menu = React.createClass({
categories: datas.categories,
active_type: datas.active_type,
active_id: datas.active_id,
+ feed_in_error: datas.feed_in_error,
all_unread_count: datas.all_unread_count});
},
});
-module.exports = {Menu: Menu, MenuFilter: MenuFilter};
+module.exports = Menu;
diff --git a/src/web/js/components/MiddlePanel.react.js b/src/web/js/components/MiddlePanel.react.js
index 756a811b..0a1dad45 100644
--- a/src/web/js/components/MiddlePanel.react.js
+++ b/src/web/js/components/MiddlePanel.react.js
@@ -1,10 +1,8 @@
var React = require('react');
-var Row = require('react-bootstrap/lib/Row');
-var Button = require('react-bootstrap/lib/Button');
-var ButtonGroup = require('react-bootstrap/lib/ButtonGroup');
-var ListGroup = require('react-bootstrap/lib/ListGroup');
-var ListGroupItem = require('react-bootstrap/lib/ListGroupItem');
-var Glyphicon = require('react-bootstrap/lib/Glyphicon');
+var Row = require('react-bootstrap/Row');
+var Button = require('react-bootstrap/Button');
+var ButtonGroup = require('react-bootstrap/ButtonGroup');
+var Glyphicon = require('react-bootstrap/Glyphicon');
var MiddlePanelStore = require('../stores/MiddlePanelStore');
var MiddlePanelActions = require('../actions/MiddlePanelActions');
@@ -36,12 +34,10 @@ var TableLine = React.createClass({
onClick={this.toogleRead} />);
var liked = (<Glyphicon glyph={this.state.liked?"star":"star-empty"}
onClick={this.toogleLike} />);
- return (
- <ListGroupItem header={title}>
- {read}
- {liked}
- {this.props.title}
- </ListGroupItem>
+ return (<div className="list-group-item">
+ <h4>{title}</h4>
+ {read} {liked} {this.props.title}
+ </div>
);
},
toogleRead: function() {
@@ -92,7 +88,7 @@ var MiddlePanel = React.createClass({
},
render: function() {
return (<Row className="show-grid">
- <ListGroup>
+ <div className="list-group">
{this.state.articles.map(function(article){
return (<TableLine key={"a" + article.article_id}
title={article.title}
@@ -104,7 +100,7 @@ var MiddlePanel = React.createClass({
feed_id={article.feed_id}
category_id={article.category_id}
feed_title={article.feed_title} />);})}
- </ListGroup>
+ </div>
</Row>
);
},
diff --git a/src/web/templates/home2.html b/src/web/templates/home2.html
index 3e9d4a6f..673d9041 100644
--- a/src/web/templates/home2.html
+++ b/src/web/templates/home2.html
@@ -1,6 +1,99 @@
-{% extends "layout.html" %}
-{% block content %}
-<section id="jarrapp"></section>
-<script type="text/javascript" src="{{ url_for("static", filename="js/bundle.min.js") }}"></script>
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ {% block head %}
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <meta name="description" content="JARR is a web-based news aggregator." />
+ <meta name="author" content="" />
+ <title>JARR{% if head_titles %} - {{ ' - '.join(head_titles) }}{% endif %}</title>
+ <link rel="shortcut icon" href="{{ url_for("static", filename="img/favicon.png") }}" />
+ <!-- Bootstrap core CSS -->
+ <link href="{{ url_for("static", filename="css/bootstrap.min.css") }}" rel="stylesheet" media="screen" />
+ <!-- Add custom CSS here -->
+ <link href="{{ url_for("static", filename="css/customized-bootstrap.css") }}" rel="stylesheet" media="screen" />
+ {% endblock %}
+ </head>
+ <body>
+ <nav class="navbar navbar-inverse navbar-fixed-top navbar-custom" role="navigation">
+ <div class="container-fluid">
+ <div class="navbar-header">
+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
+ <span class="sr-only">Toggle navigation</span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ <span class="icon-bar"></span>
+ </button>
+ <a class="navbar-brand" href="{{ url_for("home") }}">JARR</a>
+ {% if head_titles %}
+ <p class="navbar-text" style="max-height: 20px; overflow: hidden">
+ {{ " - ".join(head_titles) }}
+ </p>
+ {% endif %}
+ </div>
-{% endblock %}
+ <!-- Collect the nav links, forms, and other content for toggling -->
+ <div class="collapse navbar-collapse navbar-ex1-collapse">
+ <ul class="nav navbar-nav navbar-right">
+ {% if g.user.is_authenticated %}
+ <!-- <li><a href="{{ url_for("feed.form") }}"><span class="glyphicon glyphicon-plus-sign"></span> {{ _('Add a feed') }}</a></li> -->
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ <div><span class="glyphicon glyphicon-plus-sign"></span>&nbsp;{{ _('Add a feed') }}</div>
+ </a>
+ <ul class="dropdown-menu">
+ <li>
+ <form action="{{ url_for('feed.bookmarklet') }}" class="navbar-form navbar-left" method="GET" name="save">
+ <div class="input-group input-group-inline">
+ <input class="form-control" name="url" type="url" placeholder="{{_("site or feed url")}}" required="required"/>
+ <span class="input-group-btn">
+ <button type="submit" class="btn btn-default" /><span class="glyphicon glyphicon-plus"></span></button>
+ </span>
+ </div><!-- /input-group -->
+ </form>
+ </li>
+ </ul>
+ </li>
+ {% if conf.CRAWLING_METHOD == "classic" and (not conf.ON_HEROKU or g.user.is_admin()) %}
+ <li><a href="/fetch"><span class="glyphicon glyphicon-import"></span> {{ _('Fetch') }}</a></li>
+ {% endif %}
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ _('Feed') }} <b class="caret"></b></a>
+ <ul class="dropdown-menu">
+ <li><a href="{{ url_for("feeds.update", action="read") }}">{{ _('Mark all as read') }}</a></li>
+ <li><a href="{{ url_for("feeds.update", action="read", nb_days="1") }}">{{ _('Mark all as read older than yesterday') }}</a></li>
+ <li><a href="{{ url_for("feeds.update", action="read", nb_days="5") }}">{{ gettext('Mark all as read older than %(days)s days', days=5) }}</a></li>
+ <li><a href="{{ url_for("feeds.update", action="read", nb_days="10") }}">{{ gettext('Mark all as read older than %(days)s days', days=10) }}</a></li>
+ <li role="presentation" class="divider"></li>
+ <li><a href="{{ url_for("feeds.inactives") }}">{{ _('Inactive') }}</a></li>
+ <li><a href="{{ url_for("articles.history") }}">{{ _('History') }}</a></li>
+ <li><a href="{{ url_for("feeds.feeds") }}">{{ _('All') }}</a></li>
+ </ul>
+ </li>
+ <li class="dropdown">
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">
+ <div><span class="glyphicon glyphicon-user"></span>&nbsp;<b class="caret"></b></div>
+ </a>
+ <ul class="dropdown-menu">
+ <li><a href="{{ url_for("user.profile") }}"><span class="glyphicon glyphicon-user"></span> {{ _('Profile') }}</a></li>
+ <li><a href="{{ url_for("user.management") }}"><span class="glyphicon glyphicon-cog"></span> {{ _('Your data') }}</a></li>
+ <li><a href="{{ url_for("about") }}"><span class="glyphicon glyphicon-question-sign"></span> {{ _('About') }}</a></li>
+ {% if g.user.is_admin() %}
+ <li role="presentation" class="divider"></li>
+ <li><a href="{{ url_for("admin.dashboard") }}"><span class="glyphicon glyphicon-dashboard"></span> {{ _('Dashboard') }}</a></li>
+ <li role="presentation" class="divider"></li>
+ {% endif %}
+ <li><a href="{{ url_for("logout") }}"><span class="glyphicon glyphicon-log-out"></span> {{ _('Logout') }}</a></li>
+ </ul>
+ </li>
+ {% else %}
+ <li><a href="{{ url_for("about") }}"><span class="glyphicon glyphicon-question-sign"></span>&nbsp;{{ _('About') }}</a></li>
+ {% endif %}
+ </ul>
+ </div><!-- /.navbar-collapse -->
+ </div><!-- /.container -->
+ </nav>
+ <section id="jarrapp"></section>
+ <script type="text/javascript" src="{{ url_for('static', filename = 'js/bundle.min.js') }}"></script>
+ </body>
+</html>
bgstack15