Select the previous tab or redirect to /connect when closing a tab, move some CSS from inline react styles to classes

This commit is contained in:
khlieng 2015-05-14 01:42:25 +02:00
parent 92de7cb8ef
commit 0eca6a1823
7 changed files with 145 additions and 71 deletions

View File

@ -170,7 +170,7 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
position: fixed; position: fixed;
left: 200px; left: 200px;
top: 0; top: 0;
right: 200px; right: 0;
height: 50px; height: 50px;
padding-left: 15px; padding-left: 15px;
line-height: 50px; line-height: 50px;
@ -179,11 +179,23 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
font-size: 20px; font-size: 20px;
} }
.chat-channel .chat-title-bar {
right: 200px;
}
.chat-title-bar i { .chat-title-bar i {
padding: 0 15px; padding: 0 15px;
cursor: pointer; cursor: pointer;
} }
.chat-server .icon-search {
display: none;
}
.chat-server .userlist-bar, .chat-private .userlist-bar {
display: none;
}
.button-leave { .button-leave {
border-left: 1px solid #DDD; border-left: 1px solid #DDD;
} }
@ -226,6 +238,10 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
background: #f0f0f0; background: #f0f0f0;
} }
.chat-private .search {
right: 0;
}
.search-input { .search-input {
width: 100%; width: 100%;
padding: 15px; padding: 15px;
@ -246,10 +262,14 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
left: 200px; left: 200px;
top: 50px; top: 50px;
bottom: 50px; bottom: 50px;
right: 200px; right: 0;
z-index: 1; z-index: 1;
} }
.chat-channel .messagebox {
right: 200px;
}
.messagebox > div { .messagebox > div {
padding: 10px 15px; padding: 10px 15px;
overflow-y: auto !important; overflow-y: auto !important;

View File

@ -6,15 +6,4 @@ var tabActions = Reflux.createActions([
'select' 'select'
]); ]);
tabActions.select.preEmit = (server, channel) => {
if (channel) {
while (channel[0] === '#') {
channel = channel.slice(1);
}
routeActions.navigate('/' + server + '/' + channel);
} else {
routeActions.navigate('/' + server);
}
};
module.exports = tabActions; module.exports = tabActions;

View File

@ -7,10 +7,20 @@ var Search = require('./Search.jsx');
var MessageBox = require('./MessageBox.jsx'); var MessageBox = require('./MessageBox.jsx');
var MessageInput = require('./MessageInput.jsx'); var MessageInput = require('./MessageInput.jsx');
var UserList = require('./UserList.jsx'); var UserList = require('./UserList.jsx');
var selectedTabStore = require('../stores/selectedTab');
var tabActions = require('../actions/tab'); var tabActions = require('../actions/tab');
var Chat = React.createClass({ var Chat = React.createClass({
mixins: [Router.State], mixins: [
Router.State,
Reflux.connect(selectedTabStore, 'selectedTab')
],
getInitialState: function() {
return {
selectedTab: selectedTabStore.getState()
};
},
componentWillMount: function() { componentWillMount: function() {
if (!window.loaded) { if (!window.loaded) {
@ -25,8 +35,19 @@ var Chat = React.createClass({
}, },
render: function() { render: function() {
var chatClass;
var tab = this.state.selectedTab;
if (!tab.channel) {
chatClass = 'chat-server';
} else if (tab.channel[0] !== '#') {
chatClass = 'chat-private';
} else {
chatClass = 'chat-channel';
}
return ( return (
<div> <div className={chatClass}>
<ChatTitle /> <ChatTitle />
<Search /> <Search />
<MessageBox indent={window.messageIndent} /> <MessageBox indent={window.messageIndent} />

View File

@ -3,6 +3,7 @@ var Reflux = require('reflux');
var channelStore = require('../stores/channel'); var channelStore = require('../stores/channel');
var selectedTabStore = require('../stores/selectedTab'); var selectedTabStore = require('../stores/selectedTab');
var serverActions = require('../actions/server');
var channelActions = require('../actions/channel'); var channelActions = require('../actions/channel');
var searchActions = require('../actions/search'); var searchActions = require('../actions/search');
var privateChatActions = require('../actions/privateChat'); var privateChatActions = require('../actions/privateChat');
@ -23,9 +24,11 @@ var ChatTitle = React.createClass({
handleLeaveClick: function() { handleLeaveClick: function() {
var tab = this.state.selectedTab; var tab = this.state.selectedTab;
if (tab.channel[0] === '#') { if (!tab.channel) {
serverActions.disconnect(tab.server);
} else if (tab.channel[0] === '#') {
channelActions.part([tab.channel], tab.server); channelActions.part([tab.channel], tab.server);
} else if (tab.channel) { } else {
privateChatActions.close(tab.server, tab.channel); privateChatActions.close(tab.server, tab.channel);
} }
}, },
@ -33,26 +36,29 @@ var ChatTitle = React.createClass({
render: function() { render: function() {
var tab = this.state.selectedTab; var tab = this.state.selectedTab;
var usercount = channelStore.getUsers(tab.server, tab.channel).length; var usercount = channelStore.getUsers(tab.server, tab.channel).length;
var iconStyle = {}; var leaveTitle;
var userListStyle = {};
if (!tab.channel) { if (!tab.channel) {
iconStyle.display = 'none'; leaveTitle = 'Disconnect';
userListStyle.display = 'none';
} else if (tab.channel[0] !== '#') { } else if (tab.channel[0] !== '#') {
userListStyle.display = 'none'; leaveTitle = 'Close';
} else {
leaveTitle = 'Leave';
} }
return ( return (
<div> <div>
<div className="chat-title-bar"> <div className="chat-title-bar">
<span className="chat-title">{tab.name}</span> <span className="chat-title">{tab.name}</span>
<i className="icon-search" title="Search" style={iconStyle} onClick={searchActions.toggle}></i> <i className="icon-search" title="Search" onClick={searchActions.toggle}></i>
<i className="icon-logout button-leave" title="Leave" style={iconStyle} onClick={this.handleLeaveClick}></i> <i
className="icon-logout button-leave"
title={leaveTitle}
onClick={this.handleLeaveClick}></i>
</div> </div>
<div className="userlist-bar"> <div className="userlist-bar">
<i className="icon-user" style={userListStyle}></i> <i className="icon-user"></i>
<span className="chat-usercount" style={userListStyle}>{usercount || null}</span> <span className="chat-usercount">{usercount || null}</span>
</div> </div>
</div> </div>
); );

View File

@ -63,15 +63,10 @@ var MessageBox = React.createClass({
var tab = this.state.selectedTab; var tab = this.state.selectedTab;
var dest = tab.channel || tab.server; var dest = tab.channel || tab.server;
var lines = []; var lines = [];
var style = {};
var innerStyle = { var innerStyle = {
paddingLeft: this.props.indent + 'px' paddingLeft: this.props.indent + 'px'
}; };
if (!tab.channel || tab.channel[0] !== '#') {
style.right = 0;
}
for (var j = 0; j < this.state.messages.length; j++) { for (var j = 0; j < this.state.messages.length; j++) {
var message = this.state.messages[j]; var message = this.state.messages[j];
var messageClass = 'message'; var messageClass = 'message';
@ -96,7 +91,7 @@ var MessageBox = React.createClass({
if (lines.length !== 1) { if (lines.length !== 1) {
return ( return (
<div className="messagebox" style={style}> <div className="messagebox">
<Infinite ref="list" containerHeight={this.state.height} elementHeight={24}> <Infinite ref="list" containerHeight={this.state.height} elementHeight={24}>
{lines} {lines}
</Infinite> </Infinite>
@ -104,7 +99,7 @@ var MessageBox = React.createClass({
); );
} else { } else {
return ( return (
<div className="messagebox" style={style}> <div className="messagebox">
<div ref="list">{lines}</div> <div ref="list">{lines}</div>
</div> </div>
); );

View File

@ -9,6 +9,25 @@ var routeActions = require('../actions/route');
var privateChatActions = require('../actions/privateChat'); var privateChatActions = require('../actions/privateChat');
var selectedTab = {}; var selectedTab = {};
var history = [];
function selectPrevTab() {
history.pop();
if (history.length > 0) {
selectedTab = _.extend({}, history[history.length - 1]);
return true;
}
return false;
}
function updateChannelName(name) {
selectedTab.channel = name;
selectedTab.name = name;
history[history.length - 1].channel = name;
history[history.length - 1].name = name;
}
var selectedTabStore = Reflux.createStore({ var selectedTabStore = Reflux.createStore({
init: function() { init: function() {
@ -32,15 +51,19 @@ var selectedTabStore = Reflux.createStore({
selectedTab.name = serverStore.getName(server); selectedTab.name = serverStore.getName(server);
} }
history.push(_.extend({}, selectedTab));
this.trigger(selectedTab); this.trigger(selectedTab);
}, },
part: function(channels, server) { part: function(channels, server) {
if (server === selectedTab.server && if (server === selectedTab.server &&
channels.indexOf(selectedTab.channel) !== -1) { channels.indexOf(selectedTab.channel) !== -1) {
selectedTab.server = null; if (!selectPrevTab()) {
selectedTab.channel = null; selectedTab.channel = null;
selectedTab.name = null; selectedTab.name = serverStore.getName(server);
}
this.trigger(selectedTab); this.trigger(selectedTab);
} }
}, },
@ -48,43 +71,49 @@ var selectedTabStore = Reflux.createStore({
close: function(server, nick) { close: function(server, nick) {
if (server === selectedTab.server && if (server === selectedTab.server &&
nick === selectedTab.channel) { nick === selectedTab.channel) {
selectedTab.server = null; if (!selectPrevTab()) {
selectedTab.channel = null; selectedTab.channel = null;
selectedTab.name = null; selectedTab.name = serverStore.getName(server);
}
this.trigger(selectedTab); this.trigger(selectedTab);
} }
}, },
disconnect: function(server) { disconnect: function(server) {
if (server === selectedTab.server) { if (server === selectedTab.server) {
selectedTab = {}; _.remove(history, { server: server });
if (!selectPrevTab()) {
selectedTab = {};
}
this.trigger(selectedTab); this.trigger(selectedTab);
} }
}, },
userAdded: function(user, server, channel) { userAdded: function(user, server, channel) {
// Update the selected channel incase the casing is different
if (selectedTab.channel && if (selectedTab.channel &&
server === selectedTab.server && server === selectedTab.server &&
user === serverStore.getNick(server) && user === serverStore.getNick(server) &&
channel.toLowerCase().indexOf(selectedTab.channel.toLowerCase()) !== -1) { channel.toLowerCase().indexOf(selectedTab.channel.toLowerCase()) !== -1) {
selectedTab.channel = channel; // Update the selected channel incase the casing is different
selectedTab.name = channel; updateChannelName(channel);
this.trigger(selectedTab); this.trigger(selectedTab);
} }
}, },
loadChannels: function(channels) { loadChannels: function(channels) {
// Handle double hashtag channel names, only a single hashtag
// gets added to the channel in the URL on page load
_.each(channels, (channel) => { _.each(channels, (channel) => {
if (channel.server === selectedTab.server && if (channel.server === selectedTab.server &&
channel.name !== selectedTab.channel && channel.name !== selectedTab.channel &&
channel.name.indexOf(selectedTab.channel) !== -1) { channel.name.indexOf(selectedTab.channel) !== -1) {
selectedTab.channel = channel.name; // Handle double hashtag channel names, only a single hashtag
selectedTab.name = channel.name; // gets added to the channel in the URL on page load
updateChannelName(channel.name);
this.trigger(selectedTab); this.trigger(selectedTab);
return false;
} }
}); });
}, },
@ -92,17 +121,16 @@ var selectedTabStore = Reflux.createStore({
loadServers: function(servers) { loadServers: function(servers) {
var server = _.find(servers, { address: selectedTab.server }); var server = _.find(servers, { address: selectedTab.server });
if (!server) { if (server && !selectedTab.channel) {
selectedTab = {};
this.trigger(selectedTab);
} else if (!selectedTab.channel) {
selectedTab.name = server.name; selectedTab.name = server.name;
history[history.length - 1].name = server.name;
this.trigger(selectedTab); this.trigger(selectedTab);
} }
}, },
navigate: function(route) { navigate: function(route) {
if (route.indexOf('.') === -1) { if (route.indexOf('.') === -1 && selectedTab.server) {
selectedTab.server = null; selectedTab.server = null;
selectedTab.channel = null; selectedTab.channel = null;
this.trigger(selectedTab); this.trigger(selectedTab);
@ -123,6 +151,21 @@ var selectedTabStore = Reflux.createStore({
}); });
selectedTabStore.listen(function(selectedTab) { selectedTabStore.listen(function(selectedTab) {
var channel = selectedTab.channel;
if (selectedTab.server) {
if (channel) {
while (channel[0] === '#') {
channel = channel.slice(1);
}
routeActions.navigate('/' + selectedTab.server + '/' + channel);
} else {
routeActions.navigate('/' + selectedTab.server);
}
} else if (_.size(serverStore.getState()) === 0) {
routeActions.navigate('connect');
}
localStorage.selectedTab = JSON.stringify(selectedTab); localStorage.selectedTab = JSON.stringify(selectedTab);
}); });

File diff suppressed because one or more lines are too long