diff options
-rw-r--r-- | src/web/js/components/MainApp.react.js | 6 | ||||
-rw-r--r-- | src/web/js/components/Menu.react.js | 92 | ||||
-rw-r--r-- | src/web/static/css/one-page-app.css | 82 | ||||
-rw-r--r-- | src/web/static/css/side-nav.css | 51 | ||||
-rw-r--r-- | src/web/templates/home2.html | 1 | ||||
-rw-r--r-- | src/web/templates/layout.html | 1 | ||||
-rw-r--r-- | src/web/templates/layout.html.orig | 149 |
7 files changed, 135 insertions, 247 deletions
diff --git a/src/web/js/components/MainApp.react.js b/src/web/js/components/MainApp.react.js index 816e8c82..72504d89 100644 --- a/src/web/js/components/MainApp.react.js +++ b/src/web/js/components/MainApp.react.js @@ -11,11 +11,13 @@ var MainApp = React.createClass({ render: function() { return (<Row> <Menu /> - <Col xs={2} sm={2} md={4} lg={4}> + <Col id="middle-panel" + mdOffset={3} lgOffset={2} xs={2} sm={2} md={4} lg={4}> <MiddlePanel.MiddlePanelFilter /> <MiddlePanel.MiddlePanel /> </Col> - <Col xs={10} sm={10} md={8} lg={8}> + <Col id="right-panel" + xs={10} sm={10} md={8} lg={8}> <RightPanel.RightPanelMenu /> <RightPanel.RightPanel /> </Col> diff --git a/src/web/js/components/Menu.react.js b/src/web/js/components/Menu.react.js index 4b8c167c..75255d41 100644 --- a/src/web/js/components/Menu.react.js +++ b/src/web/js/components/Menu.react.js @@ -29,13 +29,18 @@ var FeedItem = React.createClass({ if(this.props.unread){ badge_unread = <Badge pullRight>{this.props.unread}</Badge>; } + var classes = "nav-feed"; + if(this.props.active) { + classes += " bg-primary"; + } if(this.props.error_count == 6) { - style = "danger"; + classes += " bg-danger"; } else if(this.props.error_count > 3) { - style = "warning"; + classes += " bg-warning"; } - return (<li onClick={this.handleClick}> - {icon}{this.props.title}{badge_unread} + var title = <span className="title">{this.props.title}</span>; + return (<li className={classes} onClick={this.handleClick}> + {icon}{title}{badge_unread} </li> ); }, @@ -45,25 +50,26 @@ var FeedItem = React.createClass({ }); var Category = React.createClass({ - propTypes: {category_id: React.PropTypes.number.isRequired, - filter: React.PropTypes.string.isRequired, + propTypes: {category_id: React.PropTypes.number, active_type: React.PropTypes.string, - active_id: React.PropTypes.number}, + active_id: React.PropTypes.number, + glyph: React.PropTypes.object}, render: function() { - if(this.props.active_type == 'active_id' + var classes = "nav-cat"; + if((this.props.active_type == 'category_id' + || this.props.category_id == null) && this.props.active_id == this.props.category_id) { - var classes = "success active"; - } else { - var classes = "success"; + classes += " bg-primary"; } return (<li className={classes}> + {this.props.glyph} <h4 onClick={this.handleClick}> {this.props.children} </h4> </li> ); }, - handleClick: function() { + handleClick: function(evnt) { if(this.props.category_id != null) { MiddlePanelActions.setCategoryFilter(this.props.category_id); } else { @@ -88,25 +94,25 @@ var CategoryGroup = React.createClass({ var filter = this.props.filter; var a_type = this.props.active_type; var a_id = this.props.active_id; - // filtering according to this.props.filter if(this.state.unfolded) { - var feeds = this.props.feeds.filter(function(feed) { - if (filter == 'unread' && feed.unread <= 0) { - return false; - } else if (filter == 'error' && feed.error_count <= 3) { - return false; - } - return true; - }).sort(function(feed_a, feed_b){ - return feed_b.unread - feed_a.unread; - }).map(function(feed) { - return (<FeedItem key={"f" + feed.id} feed_id={feed.id} - title={feed.title} unread={feed.unread} - error_count={feed.error_count} - active={a_type == 'feed_id' && a_id == feed.id} - icon_url={feed.icon_url} /> - ); - }); + // filtering according to this.props.filter + var feeds = this.props.feeds.filter(function(feed) { + if (filter == 'unread' && feed.unread <= 0) { + return false; + } else if (filter == 'error' && feed.error_count <= 3) { + return false; + } + return true; + }).sort(function(feed_a, feed_b){ + return feed_b.unread - feed_a.unread; + }).map(function(feed) { + return (<FeedItem key={"f" + feed.id} feed_id={feed.id} + title={feed.title} unread={feed.unread} + error_count={feed.error_count} + active={a_type == 'feed_id' && a_id == feed.id} + icon_url={feed.icon_url} /> + ); + }); } else { var feeds = []; } @@ -120,9 +126,10 @@ var CategoryGroup = React.createClass({ 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} + active_id={this.props.active_id} + active_type={this.props.active_type} + glyph={ctrl}> + <strong>{this.props.name}</strong> {unread} </Category> {feeds} </ul> @@ -143,9 +150,10 @@ var MenuFilter = React.createClass({ render: function() { var error_button = null; if (this.props.feed_in_error) { - error_button = (<Button active={this.props.filter == "error"} - onMouseDown={() => MenuActions.setFilter("error")} - bsSize="small" bsStyle="warning">Error</Button> + error_button = ( + <Button active={this.props.filter == "error"} + onMouseDown={() => MenuActions.setFilter("error")} + bsSize="small" bsStyle="warning">Error</Button> ); } return (<ButtonGroup className="nav nav-sidebar"> @@ -168,22 +176,18 @@ var Menu = React.createClass({ }, render: function() { var state = this.state; - 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}> + active_id={this.state.active_id} + active_type={this.state.active_type}> <strong>All</strong> </Category> </ul> ); - return (<Col xsHidden smHidden md={3} lg={2} className="show-grid sidebar"> + return (<Col xsHidden smHidden md={3} lg={2} data-spy="affix" + id="menu" className="show-grid sidebar"> <MenuFilter filter={this.state.filter} feed_in_error={this.state.feed_in_error} /> {rmPrntFilt} diff --git a/src/web/static/css/one-page-app.css b/src/web/static/css/one-page-app.css new file mode 100644 index 00000000..5a3444c2 --- /dev/null +++ b/src/web/static/css/one-page-app.css @@ -0,0 +1,82 @@ +#menu { + position: fixed; + top: 51px; + bottom: 0px; + left: 0px; + z-index: 1000; + display: block; + padding: 10px; + overflow-x: hidden; + overflow-y: auto; + background-color: #F5F5F5; + border-right: 1px solid #EEE; + color: #555; +} +#menu div.nav.btn-group { + margin-bottom: 10px; +} +#menu li { + padding: 2px; + cursor: pointer; + border-radius: 6px; +} +#menu li.nav-feed { + margin-left: 15px; + margin-bottom: 3px; + max-height: 22px; + overflow: hidden; +} +#menu li.nav-feed > span.badge { + top: 2px; + position: absolute; + right: 2px; +} +#menu li.nav-feed > span.title { + margin-left: 3px; +} +#menu li.bg-primary.bg-danger { + color: #fff; + background-color: orangered; +} +#menu li.bg-primary.bg-warning { + color: #fff; + background-color: gold; +} +#menu li:hover { + color: #000; + background-color: #e8e8e8; +} +#menu li.bg-primary:hover { + color: #fff; + background-color: #62a9e6; +} +#menu li.bg-warning:hover { + background-color: #f3f0da; +} +#menu li.bg-danger:hover { + background-color: #f6cab6; +} +#menu li > h4 { + padding-left: 5px; + margin: 2px; + display: inline; +} +#middle-panel { + padding-left: 20px; + padding-top: 10px; + padding-right: 20px; + position: fixed; + top: 51px; + bottom: 0px; + left: 0px; + z-index: 1000; + display: block; + overflow-x: hidden; + overflow-y: auto; + background-color: #F5F5F5; + border-right: 1px solid #EEE; +} +#middle-panel .btn-group { + margin-right: 10px; + margin-bottom: 10px; +} diff --git a/src/web/static/css/side-nav.css b/src/web/static/css/side-nav.css deleted file mode 100644 index 5128c766..00000000 --- a/src/web/static/css/side-nav.css +++ /dev/null @@ -1,51 +0,0 @@ -/* First level of nav */ -.sidenav { - margin-top: 0px; - margin-bottom: 0px; - padding-top: 10px; - padding-bottom: 0px; - overflow-y: auto; - height: 90%; - z-index: 1000; - background-color: #FFFFFF; - border-radius: 2px; - font-size: 100%; -} -/* All levels of nav */ -.sidebar .nav > li > a { - display: block; - color: #3572B0; - padding: 5px 20px; -} -.sidebar .nav > li > a:hover, -.sidebar .nav > li > a:focus { - text-decoration: none; - background-color: #F0FFFF; -} - -.sidebar .nav > .active > a, -.sidebar .nav > .active:hover > a, -.sidebar .nav > .active:focus > a { - font-weight: bold; - color: #3572B0; - background-color: transparent; -} - -.badge { - background-color: #3572B0; -} - -/* Nav: second level */ -.sidebar .nav .nav { - margin-bottom: 8px; -} -.sidebar .nav .nav > li > a { - padding-top: 3px; - padding-bottom: 3px; - font-size: 80%; -} - -li.feed-commands {display: none; text-align: right;} -li.feed-commands > span > a {margin-right: 10px;} -li.feed-menu:hover + li.feed-commands, li.feed-commands:hover {display: block;} -.glyphicon.delete, .glyphicon.like, .glyphicon.readed { cursor: pointer; } diff --git a/src/web/templates/home2.html b/src/web/templates/home2.html index 673d9041..36dd8f19 100644 --- a/src/web/templates/home2.html +++ b/src/web/templates/home2.html @@ -12,6 +12,7 @@ <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" /> + <link href="{{ url_for("static", filename="css/one-page-app.css") }}" rel="stylesheet" media="screen" /> {% endblock %} </head> <body> diff --git a/src/web/templates/layout.html b/src/web/templates/layout.html index 4b9f1a4c..ac943d54 100644 --- a/src/web/templates/layout.html +++ b/src/web/templates/layout.html @@ -12,7 +12,6 @@ <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" /> - <link href="{{ url_for("static", filename="css/side-nav.css") }}" rel="stylesheet" media="screen" /> {% endblock %} </head> <body> diff --git a/src/web/templates/layout.html.orig b/src/web/templates/layout.html.orig deleted file mode 100644 index 1abb0b68..00000000 --- a/src/web/templates/layout.html.orig +++ /dev/null @@ -1,149 +0,0 @@ - <!DOCTYPE html> -<html> - <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" /> - <link href="{{ url_for("static", filename="css/side-nav.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> - - <!-- 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> {{ _('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 page_to_render == "favorites" %} - <li><a href="{{ url_for("home") }}"><span class="glyphicon glyphicon-home"></span> {{ _('Home') }}</a></li> - {% else %} - <li><a href="{{ url_for("favorites") }}"><span class="glyphicon glyphicon-star"></span> {{ _('Favorites') }}</a></li> - {% endif %} - {% 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="10") }}">{{ _('Mark all as read older than 10 days') }}</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> <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> - - <li class="dropdown"> - <a href="#" class="dropdown-toggle" data-toggle="dropdown"> - <div><span class="glyphicon glyphicon-search"></span> <b class="caret"></b></div> - </a> - <ul class="dropdown-menu"> - <li> - <form class="navbar-form" method=get action="{{ url_for("search") }}" role="search"> - <div class="input-group"> - {% if filter_ %}<input type="hidden" name="filter_" value="{{ filter_ }}" />{% endif %} - {% if limit %}<input type="hidden" name="limit" value="{{ limit }}" />{% endif %} - {% if feed_id %}<input type="hidden" name="feed_id" value="{{ feed_id }}" />{% endif %} - <label for="search_title">{{ _("Title") }}</label> - <input type="checkbox" name="search_title" {% if search_title == 'on' or not (search_title == 'on' or search_content == 'on') %}checked{%endif%}/> - <br /> - <label for="search_content">{{ _("Content") }}</label> - <input type="checkbox" name="search_content" {% if search_content == 'on' %}checked{%endif%}/> - <input type="text" class="form-control" name="query" placeholder="{{ _("Search") }}" {% if search_query %} value="{{ search_query }}"{% endif %} /> - </div> - </form> - </li> - </ul> - </li> - {% else %} - <li><a href="{{ url_for("about") }}"><span class="glyphicon glyphicon-question-sign"></span> {{ _('About') }}</a></li> - {% endif %} - </ul> - </div><!-- /.navbar-collapse --> - </div><!-- /.container --> - </nav> - <br /> - - <div class="container not-at-home"> - {% block messages %} - {% with messages = get_flashed_messages(with_categories=true) %} - {% if messages %} - {% for category, message in messages %} - <div class="alert alert-{{category}}"> - <button type="button" class="close" data-dismiss="alert">×</button> - {{ message }} - </div> - {% endfor %} - {% endif %} - {% endwith %} - {% endblock %} - </div> - - {% block content %}{% endblock %} - - <!-- Bootstrap core JavaScript --> - <!-- Placed at the end of the document so the pages load faster --> - <script type="text/javascript" src="{{ url_for("static", filename="js/jquery.js") }}"></script> - <script type="text/javascript" src="{{ url_for("static", filename="js/bootstrap.min.js") }}"></script> - <script type="text/javascript" src="{{ url_for("static", filename="js/bundle.min.js") }}"></script> - </body> -</html> |