diff options
-rw-r--r-- | src/web/js/actions/MiddlePanelActions.js | 45 | ||||
-rw-r--r-- | src/web/js/components/MiddlePanel.react.js | 4 | ||||
-rw-r--r-- | src/web/js/stores/MenuStore.js | 30 | ||||
-rw-r--r-- | src/web/js/stores/MiddlePanelStore.js | 23 | ||||
-rw-r--r-- | src/web/views/views.py | 49 |
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): |