aboutsummaryrefslogtreecommitdiff
path: root/src/web
diff options
context:
space:
mode:
authorFrançois Schmidts <francois.schmidts@gmail.com>2016-01-27 17:14:23 +0100
committerFrançois Schmidts <francois.schmidts@gmail.com>2016-01-28 00:05:52 +0100
commitc3d6c25e52e37d772286f293f94a5dd7e1059529 (patch)
tree1d3a7e462fa82924eab9bd4a0a4434709cb0c8b1 /src/web
parentbumping react and removing react-bootstrap listgroup which are not (diff)
downloadnewspipe-c3d6c25e52e37d772286f293f94a5dd7e1059529.tar.gz
newspipe-c3d6c25e52e37d772286f293f94a5dd7e1059529.tar.bz2
newspipe-c3d6c25e52e37d772286f293f94a5dd7e1059529.zip
redoing UI and finishing up sidebar
Diffstat (limited to 'src/web')
-rw-r--r--src/web/js/components/MainApp.react.js6
-rw-r--r--src/web/js/components/Menu.react.js92
-rw-r--r--src/web/static/css/one-page-app.css82
-rw-r--r--src/web/static/css/side-nav.css51
-rw-r--r--src/web/templates/home2.html1
-rw-r--r--src/web/templates/layout.html1
-rw-r--r--src/web/templates/layout.html.orig149
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>&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 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>&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>
-
- <li class="dropdown">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown">
- <div><span class="glyphicon glyphicon-search"></span>&nbsp;<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>&nbsp;{{ _('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">&times;</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>
bgstack15