diff options
author | François Schmidts <francois.schmidts@gmail.com> | 2016-01-28 14:36:26 +0100 |
---|---|---|
committer | François Schmidts <francois.schmidts@gmail.com> | 2016-01-28 15:08:08 +0100 |
commit | 5c8f9fd0376afc034251a73023e43ada4041aa34 (patch) | |
tree | 5c97be7bfb9d40256704e5394f475b1250086fd6 /src/web | |
parent | restoring build command (diff) | |
download | newspipe-5c8f9fd0376afc034251a73023e43ada4041aa34.tar.gz newspipe-5c8f9fd0376afc034251a73023e43ada4041aa34.tar.bz2 newspipe-5c8f9fd0376afc034251a73023e43ada4041aa34.zip |
implementing search through articles
Diffstat (limited to 'src/web')
-rw-r--r-- | src/web/js/actions/MiddlePanelActions.js | 15 | ||||
-rw-r--r-- | src/web/js/components/MiddlePanel.react.js | 84 | ||||
-rw-r--r-- | src/web/js/stores/MiddlePanelStore.js | 17 | ||||
-rw-r--r-- | src/web/static/css/one-page-app.css | 7 | ||||
-rw-r--r-- | src/web/views/views.py | 13 |
5 files changed, 127 insertions, 9 deletions
diff --git a/src/web/js/actions/MiddlePanelActions.js b/src/web/js/actions/MiddlePanelActions.js index ab54217e..e1ced2a2 100644 --- a/src/web/js/actions/MiddlePanelActions.js +++ b/src/web/js/actions/MiddlePanelActions.js @@ -23,13 +23,13 @@ var shouldFetch = function(filters) { } var reloadIfNecessaryAndDispatch = function(dispath_payload) { if(shouldFetch(dispath_payload)) { - filters = MiddlePanelStore.getRequestFilter(); + var filters = MiddlePanelStore.getRequestFilter(); for (var key in filters) { if(dispath_payload[key] != null) { filters[key] = dispath_payload[key]; } } - jquery.getJSON('/middle_panel', dispath_payload, + jquery.getJSON('/middle_panel', filters, function(payload) { dispath_payload.articles = payload.articles; JarrDispatcher.dispatch(dispath_payload); @@ -52,6 +52,17 @@ var MiddlePanelActions = { }); }); }, + search: function(search) { + MiddlePanelStore._datas.display_search = true; + MiddlePanelStore._datas.query = search.query; + MiddlePanelStore._datas.search_content = search.content; + MiddlePanelStore._datas.search_content = search.content; + this.reload(); + }, + search_off: function() { + MiddlePanelStore._datas.display_search = false; + this.reload(); + }, removeParentFilter: function() { reloadIfNecessaryAndDispatch({ type: ActionTypes.PARENT_FILTER, diff --git a/src/web/js/components/MiddlePanel.react.js b/src/web/js/components/MiddlePanel.react.js index 01c8b696..b2107383 100644 --- a/src/web/js/components/MiddlePanel.react.js +++ b/src/web/js/components/MiddlePanel.react.js @@ -52,12 +52,75 @@ var TableLine = React.createClass({ }, }); +var MiddlePanelSearchRow = React.createClass({ + getInitialState: function() { + return {query: MiddlePanelStore._datas.query, + search_title: MiddlePanelStore._datas.search_title, + search_content: MiddlePanelStore._datas.search_content, + }; + }, + render: function() { + return (<Row> + <form onSubmit={this.launchSearch}> + <div className="input-group input-group-sm"> + <span className="input-group-addon"> + <span onClick={this.toogleSTitle}>Title</span> + <input id="search-title" type="checkbox" + onChange={this.toogleSTitle} + checked={this.state.search_title} + aria-label="Search title" /> + </span> + <span className="input-group-addon"> + <span onClick={this.toogleSContent}>Content</span> + <input id="search-content" type="checkbox" + onChange={this.toogleSContent} + checked={this.state.search_content} + aria-label="Search content" /> + </span> + <input type="text" className="form-control" + onChange={this.setQuery} + placeholder="Search text" /> + </div> + </form> + </Row> + ); + }, + setQuery: function(evnt) { + this.setState({query: evnt.target.value}); + }, + toogleSTitle: function() { + this.setState({search_title: !this.state.search_title}, + this.launchSearch); + }, + toogleSContent: function() { + this.setState({search_content: !this.state.search_content}, + this.launchSearch); + }, + launchSearch: function(evnt) { + if(this.state.query && (this.state.search_title + || this.state.search_content)) { + MiddlePanelActions.search({query: this.state.query, + title: this.state.search_title, + content: this.state.search_content}); + } + if(evnt) { + evnt.preventDefault(); + } + }, +}); + var MiddlePanelFilter = React.createClass({ getInitialState: function() { - return {filter: MiddlePanelStore._datas.filter}; + return {filter: MiddlePanelStore._datas.filter, + display_search: MiddlePanelStore._datas.display_search}; }, render: function() { - return (<Row className="show-grid"> + var search_row = null; + if(this.state.display_search) { + search_row = <MiddlePanelSearchRow /> + } + return (<div> + <Row className="show-grid"> <ButtonGroup> <Button active={this.state.filter == "all"} onMouseDown={this.setAllFilter} @@ -67,13 +130,22 @@ var MiddlePanelFilter = React.createClass({ bsSize="small">Unread</Button> <Button active={this.state.filter == "liked"} onMouseDown={this.setLikedFilter} - bsSize="small">Liked</Button> + bsSize="small"> + <Glyphicon glyph="star" /> + </Button> + </ButtonGroup> + <ButtonGroup> + <Button onMouseDown={this.toogleSearch} bsSize="small"> + <Glyphicon glyph="search" /> + </Button> </ButtonGroup> <ButtonGroup> <Button onMouseDown={MiddlePanelActions.markAllAsRead} bsSize="small">Mark all as read</Button> </ButtonGroup> </Row> + {search_row} + </div> ); }, setAllFilter: function() { @@ -88,6 +160,12 @@ var MiddlePanelFilter = React.createClass({ this.setState({filter: 'liked'}); MiddlePanelActions.setFilter('liked'); }, + toogleSearch: function() { + if(this.state.display_search) { + MiddlePanelActions.search_off(); + } + this.setState({display_search: !this.state.display_search}); + }, }); var MiddlePanel = React.createClass({ diff --git a/src/web/js/stores/MiddlePanelStore.js b/src/web/js/stores/MiddlePanelStore.js index bc7cee51..611808f7 100644 --- a/src/web/js/stores/MiddlePanelStore.js +++ b/src/web/js/stores/MiddlePanelStore.js @@ -7,14 +7,23 @@ var assign = require('object-assign'); var MiddlePanelStore = assign({}, EventEmitter.prototype, { _datas: {filter: 'unread', articles: [], - filter_type: null, filter_id: null}, + filter_type: null, filter_id: null, + display_search: false, query: null, + search_title: true, search_content: false}, getAll: function() { return this._datas; }, getRequestFilter: function() { - return {'filter': this._datas.filter, - 'filter_type': this._datas.filter_type, - 'filter_id': this._datas.filter_id}; + var filters = {'filter': this._datas.filter, + 'filter_type': this._datas.filter_type, + 'filter_id': this._datas.filter_id, + }; + if(this._datas.display_search) { + filters.query = this._datas.query; + filters.search_title = this._datas.search_title; + filters.search_content = this._datas.search_content; + }; + return filters; }, getArticles: function() { var key = null; diff --git a/src/web/static/css/one-page-app.css b/src/web/static/css/one-page-app.css index 5a3444c2..d25e3886 100644 --- a/src/web/static/css/one-page-app.css +++ b/src/web/static/css/one-page-app.css @@ -80,3 +80,10 @@ margin-right: 10px; margin-bottom: 10px; } +#middle-panel .btn-group:last-child { + margin-right: 0px; + float: right; +} +#middle-panel .input-group { + margin-bottom: 10px; +} diff --git a/src/web/views/views.py b/src/web/views/views.py index b4833233..90836af1 100644 --- a/src/web/views/views.py +++ b/src/web/views/views.py @@ -234,6 +234,7 @@ from flask import jsonify @app.route('/home2') +@login_required def new_home(): return render_template('home2.html') @@ -265,6 +266,18 @@ def get_menu(): def _get_filters(in_dict): filters = {} + query = in_dict.get('query') + if query: + search_title = in_dict.get('search_title') == 'true' + search_content = in_dict.get('search_content') == 'true' + if search_title: + filters['title__ilike'] = "%%%s%%" % query + if search_content: + filters['content__ilike'] = "%%%s%%" % query + if len(filters) == 0: + filters['title__ilike'] = "%%%s%%" % query + if len(filters) > 1: + filters = {"__or__": filters} if in_dict.get('filter') == 'unread': filters['readed'] = False elif in_dict.get('filter') == 'liked': |