Initial pass on MessageBox rendered with React Infinite and js line wrapping, fix line wrapping bug, disable browser line wrapping
This commit is contained in:
parent
3042ed5ec6
commit
6e223c172f
@ -8,7 +8,8 @@ var messageActions = Reflux.createActions([
|
|||||||
'add',
|
'add',
|
||||||
'broadcast',
|
'broadcast',
|
||||||
'inform',
|
'inform',
|
||||||
'command'
|
'command',
|
||||||
|
'setWrapWidth'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
messageActions.send.preEmit = function(message, to, server) {
|
messageActions.send.preEmit = function(message, to, server) {
|
||||||
|
@ -1,42 +1,70 @@
|
|||||||
var React = require('react');
|
var React = require('react');
|
||||||
var Reflux = require('reflux');
|
var Reflux = require('reflux');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
var Infinite = require('react-infinite');
|
||||||
|
|
||||||
var util = require('../util');
|
var util = require('../util');
|
||||||
var messageStore = require('../stores/message');
|
var messageStore = require('../stores/message');
|
||||||
|
var messageLineStore = require('../stores/messageLine');
|
||||||
var selectedTabStore = require('../stores/selectedTab');
|
var selectedTabStore = require('../stores/selectedTab');
|
||||||
|
var messageActions = require('../actions/message');
|
||||||
|
|
||||||
var MessageBox = React.createClass({
|
var MessageBox = React.createClass({
|
||||||
mixins: [
|
mixins: [
|
||||||
Reflux.connect(messageStore, 'messages'),
|
Reflux.connect(messageLineStore, 'lines'),
|
||||||
Reflux.connect(selectedTabStore, 'selectedTab')
|
Reflux.connect(selectedTabStore, 'selectedTab')
|
||||||
],
|
],
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
messages: messageStore.getState(),
|
lines: messageLineStore.getState(),
|
||||||
selectedTab: selectedTabStore.getState()
|
selectedTab: selectedTabStore.getState(),
|
||||||
|
height: window.innerHeight - 100
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
componentDidMount: function() {
|
||||||
|
window.addEventListener('resize', this.handleResize);
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillUnmount: function() {
|
||||||
|
window.removeEventListener('resize', this.handleResize);
|
||||||
|
},
|
||||||
|
|
||||||
componentWillUpdate: function() {
|
componentWillUpdate: function() {
|
||||||
var el = this.getDOMNode();
|
var el = this.refs.list.getDOMNode();
|
||||||
this.autoScroll = el.scrollTop + el.offsetHeight === el.scrollHeight;
|
this.autoScroll = el.scrollTop + el.offsetHeight === el.scrollHeight;
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidUpdate: function() {
|
componentDidUpdate: function() {
|
||||||
|
this.updateWidth();
|
||||||
|
|
||||||
if (this.autoScroll) {
|
if (this.autoScroll) {
|
||||||
var el = this.getDOMNode();
|
var el = this.refs.list.getDOMNode();
|
||||||
el.scrollTop = el.scrollHeight;
|
el.scrollTop = el.scrollHeight;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handleResize: function() {
|
||||||
|
this.updateWidth();
|
||||||
|
this.setState({ height: window.innerHeight - 100 });
|
||||||
|
},
|
||||||
|
|
||||||
|
updateWidth: function() {
|
||||||
|
var width = this.refs.list.getDOMNode().firstChild.offsetWidth;
|
||||||
|
|
||||||
|
if (this.width !== width) {
|
||||||
|
this.width = width;
|
||||||
|
messageActions.setWrapWidth(width);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var tab = this.state.selectedTab;
|
var tab = this.state.selectedTab;
|
||||||
var dest = tab.channel || tab.server;
|
var dest = tab.channel || tab.server;
|
||||||
var style = {}
|
var style = {}
|
||||||
|
|
||||||
var messages = _.map(messageStore.getMessages(tab.server, dest), function(message) {
|
/*var messages = _.map(messageStore.getMessages(tab.server, dest), function(message) {
|
||||||
var messageClass = 'message';
|
var messageClass = 'message';
|
||||||
|
|
||||||
if (message.type) {
|
if (message.type) {
|
||||||
@ -46,18 +74,26 @@ var MessageBox = React.createClass({
|
|||||||
return (
|
return (
|
||||||
<p className={messageClass}>
|
<p className={messageClass}>
|
||||||
<span className="message-time">{util.timestamp(message.time)}</span>
|
<span className="message-time">{util.timestamp(message.time)}</span>
|
||||||
{ message.from ? <span className="message-sender">{message.from}</span> : null }
|
{ message.from ? <span className="message-sender"> {message.from}</span> : null }
|
||||||
{message.message}
|
{' ' + message.message}
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
});
|
});*/
|
||||||
|
|
||||||
if (!tab.channel || tab.channel[0] !== '#') {
|
if (!tab.channel || tab.channel[0] !== '#') {
|
||||||
style.right = 0;
|
style.right = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lines = _.map(this.state.lines, function(line) {
|
||||||
|
return <p className="message">{line}</p>;
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="messagebox" style={style}>{messages}</div>
|
<div className="messagebox" style={style}>
|
||||||
|
<Infinite ref="list" containerHeight={this.state.height} elementHeight={24}>
|
||||||
|
{lines}
|
||||||
|
</Infinite>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
63
client/src/js/stores/messageLine.js
Normal file
63
client/src/js/stores/messageLine.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
var Reflux = require('reflux');
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
|
var util = require('../util');
|
||||||
|
var messageStore = require('./message');
|
||||||
|
var selectedTabStore = require('./selectedTab');
|
||||||
|
var messageActions = require('../actions/message');
|
||||||
|
|
||||||
|
var width = window.innerWidth;
|
||||||
|
var charWidth = util.stringWidth(' ', '16px Ubuntu Mono');
|
||||||
|
|
||||||
|
var tab = selectedTabStore.getState();
|
||||||
|
var messages;
|
||||||
|
var lines;
|
||||||
|
|
||||||
|
wrap();
|
||||||
|
|
||||||
|
function wrap() {
|
||||||
|
messages = messageStore.getMessages(tab.server, tab.channel || tab.server);
|
||||||
|
|
||||||
|
lines = util.wrap(_.map(messages, function(message) {
|
||||||
|
var line = util.timestamp(message.time);
|
||||||
|
if (message.from) {
|
||||||
|
line += ' ' + message.from;
|
||||||
|
}
|
||||||
|
line += ' ' + message.message;
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}), width, charWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
var messageLineStore = Reflux.createStore({
|
||||||
|
init: function() {
|
||||||
|
this.listenTo(messageActions.setWrapWidth, 'setWrapWidth');
|
||||||
|
this.listenTo(messageStore, 'messagesChanged');
|
||||||
|
this.listenTo(selectedTabStore, 'selectedTabChanged');
|
||||||
|
},
|
||||||
|
|
||||||
|
setWrapWidth: function(w) {
|
||||||
|
width = w;
|
||||||
|
|
||||||
|
wrap();
|
||||||
|
this.trigger(lines);
|
||||||
|
},
|
||||||
|
|
||||||
|
messagesChanged: function() {
|
||||||
|
wrap();
|
||||||
|
this.trigger(lines);
|
||||||
|
},
|
||||||
|
|
||||||
|
selectedTabChanged: function(selectedTab) {
|
||||||
|
tab = selectedTab;
|
||||||
|
|
||||||
|
wrap();
|
||||||
|
this.trigger(lines);
|
||||||
|
},
|
||||||
|
|
||||||
|
getState: function() {
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = messageLineStore;
|
@ -55,8 +55,8 @@ var selectedTabStore = Reflux.createStore({
|
|||||||
userAdded: function(user, server, channel) {
|
userAdded: function(user, server, channel) {
|
||||||
// Update the selected channel incase the casing is different
|
// Update the selected channel incase the casing is different
|
||||||
if (server === selectedTab.server &&
|
if (server === selectedTab.server &&
|
||||||
channel.toLowerCase() === selectedTab.channel.toLowerCase() &&
|
user === serverStore.getNick(server) &&
|
||||||
user === serverStore.getNick(server)) {
|
channel.toLowerCase() === selectedTab.channel.toLowerCase()) {
|
||||||
selectedTab.channel = channel;
|
selectedTab.channel = channel;
|
||||||
selectedTab.name = channel;
|
selectedTab.name = channel;
|
||||||
this.trigger(selectedTab);
|
this.trigger(selectedTab);
|
||||||
|
@ -37,13 +37,12 @@ exports.wrap = function(lines, width, charWidth) {
|
|||||||
if (wordCount !== 1) {
|
if (wordCount !== 1) {
|
||||||
wrapped.push(line);
|
wrapped.push(line);
|
||||||
|
|
||||||
line = word;
|
|
||||||
lineWidth = word.length * charWidth;
|
|
||||||
wordCount = 1;
|
|
||||||
|
|
||||||
if (i !== wlen - 1) {
|
if (i !== wlen - 1) {
|
||||||
line += ' ';
|
line = word + ' ';
|
||||||
lineWidth += charWidth;
|
lineWidth = (word.length + 1) * charWidth;
|
||||||
|
wordCount = 1;
|
||||||
|
} else {
|
||||||
|
wrapped.push(word);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wrapped.push(word);
|
wrapped.push(word);
|
||||||
|
@ -207,19 +207,24 @@ p {
|
|||||||
top: 50px;
|
top: 50px;
|
||||||
bottom: 50px;
|
bottom: 50px;
|
||||||
right: 200px;
|
right: 200px;
|
||||||
padding: 15px;
|
/*padding: 15px;*/
|
||||||
overflow: auto;
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.messagebox > div {
|
||||||
|
padding: 10px 15px;
|
||||||
|
overflow: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
.message {
|
.message {
|
||||||
margin-bottom: 5px;
|
white-space: nowrap;
|
||||||
|
/*margin-bottom: 5px;
|
||||||
padding-left: 55px;
|
padding-left: 55px;
|
||||||
text-indent: -55px;
|
text-indent: -55px;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.message span {
|
.message span {
|
||||||
margin-right: 15px;
|
/*margin-right: 15px;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-info {
|
.message-info {
|
||||||
|
Loading…
Reference in New Issue
Block a user