aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/web/js/actions/MiddlePanelActions.js45
-rw-r--r--src/web/js/components/MiddlePanel.react.js4
-rw-r--r--src/web/js/stores/MenuStore.js30
-rw-r--r--src/web/js/stores/MiddlePanelStore.js23
-rw-r--r--src/web/views/views.py49
5 files changed, 91 insertions, 60 deletions
diff --git a/src/web/js/actions/MiddlePanelActions.js b/src/web/js/actions/MiddlePanelActions.js
index 47a9958c..ab54217e 100644
--- a/src/web/js/actions/MiddlePanelActions.js
+++ b/src/web/js/actions/MiddlePanelActions.js
@@ -43,7 +43,7 @@ var reloadIfNecessaryAndDispatch = function(dispath_payload) {
var MiddlePanelActions = {
reload: function() {
- filters = MiddlePanelStore.getRequestFilter();
+ var filters = MiddlePanelStore.getRequestFilter();
jquery.getJSON('/middle_panel', filters, function(payload) {
_last_fetched_with = filters;
JarrDispatcher.dispatch({
@@ -84,19 +84,17 @@ var MiddlePanelActions = {
contentType: 'application/json',
data: JSON.stringify({readed: new_value}),
url: "api/v2.0/article/" + article_id,
- success: function (result) {
+ success: function () {
JarrDispatcher.dispatch({
type: ActionTypes.CHANGE_ATTR,
- article_id: article_id,
- category_id: category_id,
- feed_id: feed_id,
attribute: 'read',
- value: new_value,
+ value_bool: new_value,
+ value_num: new_value ? -1 : 1,
+ articles: [{article_id: article_id,
+ category_id: category_id,
+ feed_id: feed_id}],
});
},
- error: function(XMLHttpRequest, textStatus, errorThrown){
- console.log(XMLHttpRequest.responseText);
- },
});
},
changeLike: function(category_id, feed_id, article_id, new_value){
@@ -104,18 +102,33 @@ var MiddlePanelActions = {
contentType: 'application/json',
data: JSON.stringify({like: new_value}),
url: "api/v2.0/article/" + article_id,
- success: function (result) {
+ success: function () {
JarrDispatcher.dispatch({
type: ActionTypes.CHANGE_ATTR,
- article_id: article_id,
- category_id: category_id,
- feed_id: feed_id,
attribute: 'liked',
- value: new_value,
+ value_bool: new_value,
+ value_num: new_value ? -1 : 1,
+ articles: [{article_id: article_id,
+ category_id: category_id,
+ feed_id: feed_id}],
});
},
- error: function(XMLHttpRequest, textStatus, errorThrown){
- console.log(XMLHttpRequest.responseText);
+ });
+ },
+ markAllAsRead: function() {
+ var filters = MiddlePanelStore.getRequestFilter();
+ jquery.ajax({type: 'PUT',
+ contentType: 'application/json',
+ data: JSON.stringify(filters),
+ url: "/mark_all_as_read",
+ success: function (payload) {
+ JarrDispatcher.dispatch({
+ type: ActionTypes.CHANGE_ATTR,
+ attribute: 'read',
+ value_num: -1,
+ value_bool: true,
+ articles: payload.articles,
+ });
},
});
},
diff --git a/src/web/js/components/MiddlePanel.react.js b/src/web/js/components/MiddlePanel.react.js
index e0ea8110..756a811b 100644
--- a/src/web/js/components/MiddlePanel.react.js
+++ b/src/web/js/components/MiddlePanel.react.js
@@ -73,6 +73,10 @@ var MiddlePanelFilter = React.createClass({
onMouseDown={() => this.setFilter("liked")}
bsSize="small">Liked</Button>
</ButtonGroup>
+ <ButtonGroup>
+ <Button onMouseDown={MiddlePanelActions.markAllAsRead}
+ bsSize="small">Mark all as read</Button>
+ </ButtonGroup>
</Row>
);
},
diff --git a/src/web/js/stores/MenuStore.js b/src/web/js/stores/MenuStore.js
index ecf32499..d98495f5 100644
--- a/src/web/js/stores/MenuStore.js
+++ b/src/web/js/stores/MenuStore.js
@@ -63,27 +63,23 @@ MenuStore.dispatchToken = JarrDispatcher.register(function(action) {
if(action.attribute != 'read') {
return;
}
- for(var i in MenuStore._datas.categories) {
- if(MenuStore._datas.categories[i].id == action.category_id) {
- for(var j in MenuStore._datas.categories[i].feeds) {
- if(MenuStore._datas.categories[i].feeds[j].id == action.feed_id) {
- if(action.value) {
- MenuStore._datas.categories[i].feeds[j].unread -= 1;
- } else {
- MenuStore._datas.categories[i].feeds[j].unread += 1;
- }
+ var val = action.value_num;
+ action.articles.map(function(article) {
+ for(var i in MenuStore._datas.categories) {
+ if(MenuStore._datas.categories[i].id == article.category_id) {
+ for(var j in MenuStore._datas.categories[i].feeds) {
+ if(MenuStore._datas.categories[i].feeds[j].id == article.feed_id) {
+ MenuStore._datas.categories[i].feeds[j].unread += val;
+ break;
+ }
}
+ MenuStore._datas.categories[i].unread += val;
+ break;
}
- if(action.value) {
- MenuStore._datas.categories[i].unread -= 1;
- } else {
- MenuStore._datas.categories[i].unread += 1;
- }
- MenuStore.emitChange();
- break;
}
- }
+ });
+ MenuStore.emitChange();
break;
default:
// do nothing
diff --git a/src/web/js/stores/MiddlePanelStore.js b/src/web/js/stores/MiddlePanelStore.js
index 12c2d6e8..bc7cee51 100644
--- a/src/web/js/stores/MiddlePanelStore.js
+++ b/src/web/js/stores/MiddlePanelStore.js
@@ -84,21 +84,22 @@ MiddlePanelStore.dispatchToken = JarrDispatcher.register(function(action) {
if(changed) {MiddlePanelStore.emitChange();}
break;
case ActionTypes.CHANGE_ATTR:
- var id = action.article_id;
var attr = action.attribute;
- var val = action.value;
- for (var i in MiddlePanelStore._datas.articles) {
- if(MiddlePanelStore._datas.articles[i].article_id == id) {
- if (MiddlePanelStore._datas.articles[i][attr] != val) {
- MiddlePanelStore._datas.articles[i][attr] = val;
- // avoiding redraw if not filter, display won't change anyway
- if(MiddlePanelStore._datas.filter != 'all') {
- MiddlePanelStore.emitChange();
+ var val = action.value_bool;
+ action.articles.map(function(article) {
+ for (var i in MiddlePanelStore._datas.articles) {
+ if(MiddlePanelStore._datas.articles[i].article_id == article.article_id) {
+ if (MiddlePanelStore._datas.articles[i][attr] != val) {
+ MiddlePanelStore._datas.articles[i][attr] = val;
+ // avoiding redraw if not filter, display won't change anyway
+ if(MiddlePanelStore._datas.filter != 'all') {
+ MiddlePanelStore.emitChange();
+ }
}
+ break;
}
- break;
}
- }
+ });
break;
default:
// pass
diff --git a/src/web/views/views.py b/src/web/views/views.py
index e296c8ac..b4833233 100644
--- a/src/web/views/views.py
+++ b/src/web/views/views.py
@@ -263,32 +263,49 @@ def get_menu():
'all_unread_count': sum(unread.values())})
-@app.route('/middle_panel')
-@login_required
-def get_middle_panel():
+def _get_filters(in_dict):
filters = {}
- if request.args.get('filter') == 'unread':
+ if in_dict.get('filter') == 'unread':
filters['readed'] = False
- elif request.args.get('filter') == 'liked':
+ elif in_dict.get('filter') == 'liked':
filters['like'] = True
- filter_type = request.args.get('filter_type')
- if filter_type in {'feed', 'category'} and request.args.get('filter_id'):
- filters[filter_type + '_id'] = int(request.args['filter_id']) or None
+ filter_type = in_dict.get('filter_type')
+ if filter_type in {'feed_id', 'category_id'} and in_dict.get('filter_id'):
+ filters[filter_type] = int(in_dict['filter_id']) or None
+ return filters
- fd_hash = {feed.id: {'title': feed.title,
- 'icon_url': url_for('icon.icon', url=feed.icon_url)
- if feed.icon_url else None}
- for feed in FeedController(g.user.id).read()}
- articles = ArticleController(g.user.id).read(**filters)\
- .order_by(Article.date.desc())
+
+def _articles_to_json(articles, fd_hash=None):
return jsonify(**{'articles': [{'title': art.title, 'liked': art.like,
'read': art.readed, 'article_id': art.id,
'feed_id': art.feed_id, 'category_id': art.category_id or 0,
- 'feed_title': fd_hash[art.feed_id]['title'],
- 'icon_url': fd_hash[art.feed_id]['icon_url'],
+ 'feed_title': fd_hash[art.feed_id]['title'] if fd_hash else None,
+ 'icon_url': fd_hash[art.feed_id]['icon_url'] if fd_hash else None,
'date': art.date} for art in articles.limit(1000)]})
+@app.route('/middle_panel')
+@login_required
+def get_middle_panel():
+ filters = _get_filters(request.args)
+ art_contr = ArticleController(g.user.id)
+ fd_hash = {feed.id: {'title': feed.title,
+ 'icon_url': url_for('icon.icon', url=feed.icon_url)
+ if feed.icon_url else None}
+ for feed in FeedController(g.user.id).read()}
+ articles = art_contr.read(**filters).order_by(Article.date.desc())
+ return _articles_to_json(articles, fd_hash)
+
+
+@app.route('/mark_all_as_read', methods=['PUT'])
+@login_required
+def mark_all_as_read():
+ filters, acontr = _get_filters(request.json), ArticleController(g.user.id)
+ articles = _articles_to_json(acontr.read(**filters))
+ acontr.update(filters, {'readed': True})
+ return articles
+
+
@etag_match
def render_home(filters=None, head_titles=None,
page_to_render='home', **kwargs):
bgstack15