Add early search prototype on the client, add leave button
This commit is contained in:
parent
deba58dbff
commit
7aae7685c5
19 changed files with 297 additions and 60 deletions
15
client/src/js/actions/search.js
Normal file
15
client/src/js/actions/search.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
var Reflux = require('reflux');
|
||||
|
||||
var socket = require('../socket');
|
||||
|
||||
var searchActions = Reflux.createActions([
|
||||
'search',
|
||||
'searchDone',
|
||||
'toggle'
|
||||
]);
|
||||
|
||||
searchActions.search.preEmit = (server, channel, phrase) => {
|
||||
socket.send('search', { server, channel, phrase });
|
||||
};
|
||||
|
||||
module.exports = searchActions;
|
|
@ -3,6 +3,7 @@ var Reflux = require('reflux');
|
|||
var Router = require('react-router');
|
||||
|
||||
var ChatTitle = require('./ChatTitle.jsx');
|
||||
var Search = require('./Search.jsx');
|
||||
var MessageBox = require('./MessageBox.jsx');
|
||||
var MessageInput = require('./MessageInput.jsx');
|
||||
var UserList = require('./UserList.jsx');
|
||||
|
@ -27,6 +28,7 @@ var Chat = React.createClass({
|
|||
return (
|
||||
<div>
|
||||
<ChatTitle />
|
||||
<Search />
|
||||
<MessageBox indent={window.messageIndent} />
|
||||
<MessageInput />
|
||||
<UserList />
|
||||
|
|
|
@ -3,6 +3,9 @@ var Reflux = require('reflux');
|
|||
|
||||
var channelStore = require('../stores/channel');
|
||||
var selectedTabStore = require('../stores/selectedTab');
|
||||
var channelActions = require('../actions/channel');
|
||||
var searchActions = require('../actions/search');
|
||||
var privateChatActions = require('../actions/privateChat');
|
||||
|
||||
var ChatTitle = React.createClass({
|
||||
mixins: [
|
||||
|
@ -17,16 +20,40 @@ var ChatTitle = React.createClass({
|
|||
};
|
||||
},
|
||||
|
||||
handleLeaveClick: function() {
|
||||
var tab = this.state.selectedTab;
|
||||
|
||||
if (tab.channel[0] === '#') {
|
||||
channelActions.part([tab.channel], tab.server);
|
||||
} else if (tab.channel) {
|
||||
privateChatActions.close(tab.server, tab.channel);
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var tab = this.state.selectedTab;
|
||||
var usercount = channelStore.getUsers(tab.server, tab.channel).length;
|
||||
var iconStyle = {};
|
||||
var userListStyle = {};
|
||||
|
||||
if (!tab.channel) {
|
||||
iconStyle.display = 'none';
|
||||
userListStyle.display = 'none';
|
||||
} else if (tab.channel[0] !== '#') {
|
||||
userListStyle.display = 'none';
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="chat-title-bar">
|
||||
<div>
|
||||
<div>
|
||||
<div className="chat-title-bar">
|
||||
<span className="chat-title">{tab.name}</span>
|
||||
<i className="icon-search" title="Search" style={iconStyle} onClick={searchActions.toggle}></i>
|
||||
<i className="icon-logout button-leave" title="Leave" style={iconStyle} onClick={this.handleLeaveClick}></i>
|
||||
</div>
|
||||
<div className="userlist-bar">
|
||||
<i className="icon-user" style={userListStyle}></i>
|
||||
<span className="chat-usercount" style={userListStyle}>{usercount || null}</span>
|
||||
</div>
|
||||
<span className="chat-usercount">{usercount || null}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
61
client/src/js/components/Search.jsx
Normal file
61
client/src/js/components/Search.jsx
Normal file
|
@ -0,0 +1,61 @@
|
|||
var React = require('react');
|
||||
var Reflux = require('reflux');
|
||||
var _ = require('lodash');
|
||||
|
||||
var util = require('../util');
|
||||
var searchStore = require('../stores/search');
|
||||
var selectedTabStore = require('../stores/selectedTab');
|
||||
var searchActions = require('../actions/search');
|
||||
|
||||
var Search = React.createClass({
|
||||
mixins: [
|
||||
Reflux.connect(searchStore),
|
||||
Reflux.connect(selectedTabStore, 'selectedTab')
|
||||
],
|
||||
|
||||
getInitialState: function() {
|
||||
var state = _.extend({}, searchStore.getState());
|
||||
state.selectedTab = selectedTabStore.getState();
|
||||
|
||||
return state;
|
||||
},
|
||||
|
||||
componentDidUpdate: function(prevProps, prevState) {
|
||||
if (!prevState.show && this.state.show) {
|
||||
this.refs.input.getDOMNode().focus();
|
||||
}
|
||||
},
|
||||
|
||||
handleChange: function(e) {
|
||||
var tab = this.state.selectedTab;
|
||||
|
||||
if (tab.channel) {
|
||||
searchActions.search(tab.server, tab.channel, e.target.value);
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var style = {
|
||||
display: this.state.show ? 'block' : 'none'
|
||||
};
|
||||
|
||||
var results = _.map(this.state.results, (result) => {
|
||||
return (
|
||||
<p key={result.id}>{util.timestamp(new Date(result.time * 1000))} {result.from} {result.content}</p>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="search" style={style}>
|
||||
<input
|
||||
ref="input"
|
||||
className="search-input"
|
||||
type="text"
|
||||
onChange={this.handleChange} />
|
||||
<div className="search-results">{results}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Search;
|
|
@ -69,6 +69,7 @@ var TabList = React.createClass({
|
|||
<button className="button-connect" onClick={this.handleConnectClick}>Connect</button>
|
||||
{tabs}
|
||||
<div className="side-buttons">
|
||||
<i className="icon-user"></i>
|
||||
<i className="icon-cog" onClick={this.handleSettingsClick}></i>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,6 +7,7 @@ var messageActions = require('./actions/message');
|
|||
var serverActions = require('./actions/server');
|
||||
var routeActions = require('./actions/route');
|
||||
var tabActions = require('./actions/tab');
|
||||
var searchActions = require('./actions/search');
|
||||
|
||||
socket.on('join', function(data) {
|
||||
channelActions.addUser(data.user, data.server, data.channels[0]);
|
||||
|
@ -85,6 +86,10 @@ socket.on('channels', function(data) {
|
|||
channelActions.load(data);
|
||||
});
|
||||
|
||||
socket.on('search', function(data) {
|
||||
searchActions.searchDone(data.results);
|
||||
});
|
||||
|
||||
serverActions.connect.listen(function(server, nick, opts) {
|
||||
messageActions.inform('Connecting...', server);
|
||||
});
|
||||
|
|
|
@ -34,7 +34,7 @@ var privateChatStore = Reflux.createStore({
|
|||
},
|
||||
|
||||
close: function(server, nick) {
|
||||
delete privateChat[server][nick];
|
||||
delete privateChats[server][nick];
|
||||
this.trigger(privateChats);
|
||||
},
|
||||
|
||||
|
|
30
client/src/js/stores/search.js
Normal file
30
client/src/js/stores/search.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
var Reflux = require('reflux');
|
||||
|
||||
var actions = require('../actions/search');
|
||||
|
||||
var state = {
|
||||
show: false,
|
||||
results: []
|
||||
};
|
||||
|
||||
var searchStore = Reflux.createStore({
|
||||
init: function() {
|
||||
this.listenToMany(actions);
|
||||
},
|
||||
|
||||
searchDone: function(results) {
|
||||
state.results = results;
|
||||
this.trigger(state);
|
||||
},
|
||||
|
||||
toggle: function() {
|
||||
state.show = !state.show;
|
||||
this.trigger(state);
|
||||
},
|
||||
|
||||
getState: function() {
|
||||
return state;
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = searchStore;
|
|
@ -6,6 +6,7 @@ var actions = require('../actions/tab');
|
|||
var channelActions = require('../actions/channel');
|
||||
var serverActions = require('../actions/server');
|
||||
var routeActions = require('../actions/route');
|
||||
var privateChatActions = require('../actions/privateChat');
|
||||
|
||||
var selectedTab = {};
|
||||
|
||||
|
@ -13,6 +14,7 @@ var selectedTabStore = Reflux.createStore({
|
|||
init: function() {
|
||||
this.listenToMany(actions);
|
||||
this.listenTo(channelActions.part, 'part');
|
||||
this.listenTo(privateChatActions.close, 'close');
|
||||
this.listenTo(serverActions.disconnect, 'disconnect');
|
||||
this.listenTo(channelActions.addUser, 'userAdded');
|
||||
this.listenTo(channelActions.load, 'loadChannels');
|
||||
|
@ -43,6 +45,16 @@ var selectedTabStore = Reflux.createStore({
|
|||
}
|
||||
},
|
||||
|
||||
close: function(server, nick) {
|
||||
if (server === selectedTab.server &&
|
||||
nick === selectedTab.channel) {
|
||||
selectedTab.server = null;
|
||||
selectedTab.channel = null;
|
||||
selectedTab.name = null;
|
||||
this.trigger(selectedTab);
|
||||
}
|
||||
},
|
||||
|
||||
disconnect: function(server) {
|
||||
if (server === selectedTab.server) {
|
||||
selectedTab = {};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue