summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
author=Corey Hulen <corey@hulen.com>2015-09-02 09:45:12 -0700
committer=Corey Hulen <corey@hulen.com>2015-09-02 09:45:12 -0700
commit63bc243b179f2c1f7b51ad2252f698907d2cde59 (patch)
tree0c6419ed2602a3b75f2b49e26fac75289f3044af /web
parentf578bb1e48ec4d97bca92c7faf0dd8ed5aeceb39 (diff)
downloadchat-63bc243b179f2c1f7b51ad2252f698907d2cde59.tar.gz
chat-63bc243b179f2c1f7b51ad2252f698907d2cde59.tar.bz2
chat-63bc243b179f2c1f7b51ad2252f698907d2cde59.zip
MM-2065 breaking seach_results into multiple files
Diffstat (limited to 'web')
-rw-r--r--web/react/components/search_results.jsx218
-rw-r--r--web/react/components/search_results_header.jsx61
-rw-r--r--web/react/components/search_results_item.jsx105
3 files changed, 239 insertions, 145 deletions
diff --git a/web/react/components/search_results.jsx b/web/react/components/search_results.jsx
index b1efd7685..6ee817171 100644
--- a/web/react/components/search_results.jsx
+++ b/web/react/components/search_results.jsx
@@ -1,181 +1,109 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
-
var PostStore = require('../stores/post_store.jsx');
-var ChannelStore = require('../stores/channel_store.jsx');
var UserStore = require('../stores/user_store.jsx');
-var UserProfile = require( './user_profile.jsx' );
-var SearchBox =require('./search_bar.jsx');
+var SearchBox = require('./search_bar.jsx');
var utils = require('../utils/utils.jsx');
-var client = require('../utils/client.jsx');
-var AsyncClient = require('../utils/async_client.jsx');
-var AppDispatcher = require('../dispatcher/app_dispatcher.jsx');
-var Constants = require('../utils/constants.jsx');
-var ActionTypes = Constants.ActionTypes;
-
-var RhsHeaderSearch = React.createClass({
- handleClose: function(e) {
- e.preventDefault();
-
- AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH,
- results: null
- });
-
- AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH_TERM,
- term: null,
- do_search: false,
- is_mention_search: false
- });
-
- AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST_SELECTED,
- results: null
- });
- },
- render: function() {
- var title = this.props.isMentionSearch ? "Recent Mentions" : "Search Results";
- return (
- <div className="sidebar--right__header">
- <span className="sidebar--right__title">{title}</span>
- <button type="button" className="sidebar--right__close" aria-label="Close" title="Close" onClick={this.handleClose}></button>
- </div>
- );
- }
-});
-
-var SearchItem = React.createClass({
- handleClick: function(e) {
- e.preventDefault();
+var SearchResultsHeader = require('./search_results_header.jsx');
+var SearchResultsItem = require('./search_results_item.jsx');
- var self = this;
-
- client.getPost(
- this.props.post.channel_id,
- this.props.post.id,
- function(data) {
-
- AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_POST_SELECTED,
- post_list: data,
- from_search: PostStore.getSearchTerm()
- });
-
- AppDispatcher.handleServerAction({
- type: ActionTypes.RECIEVED_SEARCH,
- results: null,
- is_mention_search: self.props.isMentionSearch
- });
- },
- function(err) {
- AsyncClient.dispatchError(err, "getPost");
- }
- );
-
- var postChannel = ChannelStore.get(this.props.post.channel_id);
- var teammate = postChannel.type === 'D' ? utils.getDirectTeammate(this.props.post.channel_id).username : "";
-
- utils.switchChannel(postChannel, teammate);
- },
+function getStateFromStores() {
+ return {results: PostStore.getSearchResults()};
+}
- render: function() {
+export default class SearchResults extends React.Component {
+ constructor(props) {
+ super(props);
- var message = utils.textToJsx(this.props.post.message, {searchTerm: this.props.term, noMentionHighlight: !this.props.isMentionSearch});
- var channelName = "";
- var channel = ChannelStore.get(this.props.post.channel_id);
- var timestamp = UserStore.getCurrentUser().update_at;
+ this.mounted = false;
- if (channel) {
- channelName = (channel.type === 'D') ? "Private Message" : channel.display_name;
- }
+ this.onChange = this.onChange.bind(this);
+ this.resize = this.resize.bind(this);
- return (
- <div className="search-item-container post" onClick={this.handleClick}>
- <div className="search-channel__name">{ channelName }</div>
- <div className="post-profile-img__container">
- <img className="post-profile-img" src={"/api/v1/users/" + this.props.post.user_id + "/image?time=" + timestamp} height="36" width="36" />
- </div>
- <div className="post__content">
- <ul className="post-header">
- <li className="post-header-col"><strong><UserProfile userId={this.props.post.user_id} /></strong></li>
- <li className="post-header-col">
- <time className="search-item-time">
- { utils.displayDate(this.props.post.create_at) + ' ' + utils.displayTime(this.props.post.create_at) }
- </time>
- </li>
- </ul>
- <div className="search-item-snippet"><span>{message}</span></div>
- </div>
- </div>
- );
+ this.state = getStateFromStores();
}
-});
-
-function getStateFromStores() {
- return { results: PostStore.getSearchResults() };
-}
-
-module.exports = React.createClass({
- displayName: 'SearchResults',
- componentDidMount: function() {
- PostStore.addSearchChangeListener(this._onChange);
+ componentDidMount() {
+ this.mounted = true;
+ PostStore.addSearchChangeListener(this.onChange);
this.resize();
var self = this;
- $(window).resize(function(){
+ $(window).resize(function resize() {
self.resize();
});
- },
- componentDidUpdate: function() {
+ }
+
+ componentDidUpdate() {
this.resize();
- },
- componentWillUnmount: function() {
- PostStore.removeSearchChangeListener(this._onChange);
- },
- _onChange: function() {
- if (this.isMounted()) {
+ }
+
+ componentWillUnmount() {
+ PostStore.removeSearchChangeListener(this.onChange);
+ this.mounted = false;
+ }
+
+ onChange() {
+ if (this.mounted) {
var newState = getStateFromStores();
if (!utils.areStatesEqual(newState, this.state)) {
this.setState(newState);
}
}
- },
- getInitialState: function() {
- return getStateFromStores();
- },
- resize: function() {
+ }
+
+ resize() {
var height = $(window).height() - $('#error_bar').outerHeight() - 100;
- $("#search-items-container").css("height", height + "px");
- $("#search-items-container").scrollTop(0);
- $("#search-items-container").perfectScrollbar();
- },
- render: function() {
+ $('#search-items-container').css('height', height + 'px');
+ $('#search-items-container').scrollTop(0);
+ $('#search-items-container').perfectScrollbar();
+ }
+ render() {
var results = this.state.results;
var currentId = UserStore.getCurrentId();
- var searchForm = currentId ? <SearchBox /> : null;
+ var searchForm = null;
+ if (currentId) {
+ searchForm = <SearchBox />;
+ }
var noResults = (!results || !results.order || !results.order.length);
var searchTerm = PostStore.getSearchTerm();
- return (
- <div className="sidebar--right__content">
- <div className="search-bar__container sidebar--right__search-header">{searchForm}</div>
- <div className="sidebar-right__body">
- <RhsHeaderSearch isMentionSearch={this.props.isMentionSearch} />
- <div id="search-items-container" className="search-items-container">
-
- { noResults ? <div className="sidebar--right__subheader">No results</div>
- : results.order.map(function(id) {
- var post = results.posts[id];
- return <SearchItem key={post.id} post={post} term={searchTerm} isMentionSearch={this.props.isMentionSearch} />
- }, this)
- }
+ var ctls = null;
+
+ if (noResults) {
+ ctls = <div className='sidebar--right__subheader'>No results</div>;
+ } else {
+ ctls = results.order.map(function mymap(id) {
+ var post = results.posts[id];
+ return (
+ <SearchResultsItem
+ key={post.id}
+ post={post}
+ term={searchTerm}
+ isMentionSearch={this.props.isMentionSearch}
+ />
+ );
+ }, this);
+ }
+ return (
+ <div className='sidebar--right__content'>
+ <div className='search-bar__container sidebar--right__search-header'>{searchForm}</div>
+ <div className='sidebar-right__body'>
+ <SearchResultsHeader isMentionSearch={this.props.isMentionSearch} />
+ <div
+ id='search-items-container'
+ className='search-items-container'
+ >
+ {ctls}
</div>
</div>
</div>
);
}
-});
+}
+
+SearchResults.propTypes = {
+ isMentionSearch: React.PropTypes.bool
+};
diff --git a/web/react/components/search_results_header.jsx b/web/react/components/search_results_header.jsx
new file mode 100644
index 000000000..694f0c55d
--- /dev/null
+++ b/web/react/components/search_results_header.jsx
@@ -0,0 +1,61 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+var AppDispatcher = require('../dispatcher/app_dispatcher.jsx');
+var Constants = require('../utils/constants.jsx');
+var ActionTypes = Constants.ActionTypes;
+
+export default class SearchResultsHeader extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.handleClose = this.handleClose.bind(this);
+ }
+
+ handleClose(e) {
+ e.preventDefault();
+
+ AppDispatcher.handleServerAction({
+ type: ActionTypes.RECIEVED_SEARCH,
+ results: null
+ });
+
+ AppDispatcher.handleServerAction({
+ type: ActionTypes.RECIEVED_SEARCH_TERM,
+ term: null,
+ do_search: false,
+ is_mention_search: false
+ });
+
+ AppDispatcher.handleServerAction({
+ type: ActionTypes.RECIEVED_POST_SELECTED,
+ results: null
+ });
+ }
+
+ render() {
+ var title = 'Search Results';
+
+ if (this.props.isMentionSearch) {
+ title = 'Recent Mentions';
+ }
+
+ return (
+ <div className='sidebar--right__header'>
+ <span className='sidebar--right__title'>{title}</span>
+ <button
+ type='button'
+ className='sidebar--right__close'
+ aria-label='Close'
+ title='Close'
+ onClick={this.handleClose}
+ >
+ </button>
+ </div>
+ );
+ }
+}
+
+SearchResultsHeader.propTypes = {
+ isMentionSearch: React.PropTypes.bool
+}; \ No newline at end of file
diff --git a/web/react/components/search_results_item.jsx b/web/react/components/search_results_item.jsx
new file mode 100644
index 000000000..aa56f1174
--- /dev/null
+++ b/web/react/components/search_results_item.jsx
@@ -0,0 +1,105 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+var PostStore = require('../stores/post_store.jsx');
+var ChannelStore = require('../stores/channel_store.jsx');
+var UserStore = require('../stores/user_store.jsx');
+var UserProfile = require('./user_profile.jsx');
+var utils = require('../utils/utils.jsx');
+var client = require('../utils/client.jsx');
+var AsyncClient = require('../utils/async_client.jsx');
+var AppDispatcher = require('../dispatcher/app_dispatcher.jsx');
+var Constants = require('../utils/constants.jsx');
+var ActionTypes = Constants.ActionTypes;
+
+export default class SearchResultsItem extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.handleClick = this.handleClick.bind(this);
+ }
+
+ handleClick(e) {
+ e.preventDefault();
+
+ var self = this;
+
+ client.getPost(
+ this.props.post.channel_id,
+ this.props.post.id,
+ function success(data) {
+ AppDispatcher.handleServerAction({
+ type: ActionTypes.RECIEVED_POST_SELECTED,
+ post_list: data,
+ from_search: PostStore.getSearchTerm()
+ });
+
+ AppDispatcher.handleServerAction({
+ type: ActionTypes.RECIEVED_SEARCH,
+ results: null,
+ is_mention_search: self.props.isMentionSearch
+ });
+ },
+ function success(err) {
+ AsyncClient.dispatchError(err, 'getPost');
+ }
+ );
+
+ var postChannel = ChannelStore.get(this.props.post.channel_id);
+ var teammate = '';
+
+ if (postChannel.type === 'D') {
+ teammate = utils.getDirectTeammate(this.props.post.channel_id).username;
+ }
+
+ utils.switchChannel(postChannel, teammate);
+ }
+
+ render() {
+ var message = utils.textToJsx(this.props.post.message, {searchTerm: this.props.term, noMentionHighlight: !this.props.isMentionSearch});
+ var channelName = '';
+ var channel = ChannelStore.get(this.props.post.channel_id);
+ var timestamp = UserStore.getCurrentUser().update_at;
+
+ if (channel) {
+ channelName = channel.display_name;
+ if (channel.type === 'D') {
+ channelName = 'Private Message';
+ }
+ }
+
+ return (
+ <div
+ className='search-item-container post'
+ onClick={this.handleClick}
+ >
+ <div className='search-channel__name'>{channelName}</div>
+ <div className='post-profile-img__container'>
+ <img
+ className='post-profile-img'
+ src={'/api/v1/users/' + this.props.post.user_id + '/image?time=' + timestamp}
+ height='36'
+ width='36'
+ />
+ </div>
+ <div className='post__content'>
+ <ul className='post-header'>
+ <li className='post-header-col'><strong><UserProfile userId={this.props.post.user_id} /></strong></li>
+ <li className='post-header-col'>
+ <time className='search-item-time'>
+ {utils.displayDate(this.props.post.create_at) + ' ' + utils.displayTime(this.props.post.create_at)}
+ </time>
+ </li>
+ </ul>
+ <div className='search-item-snippet'><span>{message}</span></div>
+ </div>
+ </div>
+ );
+ }
+}
+
+SearchResultsItem.propTypes = {
+ post: React.PropTypes.object,
+ isMentionSearch: React.PropTypes.bool,
+ term: React.PropTypes.string
+}; \ No newline at end of file