summaryrefslogtreecommitdiffstats
path: root/web/react
diff options
context:
space:
mode:
author=Corey Hulen <corey@hulen.com>2015-09-17 09:21:56 -0700
committer=Corey Hulen <corey@hulen.com>2015-09-17 09:21:56 -0700
commit9b5198c69c01ff11b0977282b61cf2222ef2f2b1 (patch)
treea5179226ff013f082a6629dbf888454c53611383 /web/react
parent51c3445e694e68fdecd809f17fbaa64751e5931c (diff)
parent3edd8dbdf65e0b7be422a46328cb85482aa78f69 (diff)
downloadchat-9b5198c69c01ff11b0977282b61cf2222ef2f2b1.tar.gz
chat-9b5198c69c01ff11b0977282b61cf2222ef2f2b1.tar.bz2
chat-9b5198c69c01ff11b0977282b61cf2222ef2f2b1.zip
Merge branch 'master' into PLT-92
Diffstat (limited to 'web/react')
-rw-r--r--web/react/components/post_body.jsx28
-rw-r--r--web/react/components/sidebar.jsx71
-rw-r--r--web/react/components/unread_channel_indicator.jsx35
-rw-r--r--web/react/components/user_settings_modal.jsx2
4 files changed, 100 insertions, 36 deletions
diff --git a/web/react/components/post_body.jsx b/web/react/components/post_body.jsx
index df4ed3d57..3be615bb9 100644
--- a/web/react/components/post_body.jsx
+++ b/web/react/components/post_body.jsx
@@ -17,19 +17,42 @@ export default class PostBody extends React.Component {
const linkData = Utils.extractLinks(this.props.post.message);
this.state = {links: linkData.links, message: linkData.text};
}
+
+ getAllChildNodes(nodeIn) {
+ var textNodes = [];
+
+ function getTextNodes(node) {
+ textNodes.push(node);
+
+ for (var i = 0, len = node.childNodes.length; i < len; ++i) {
+ getTextNodes(node.childNodes[i]);
+ }
+ }
+
+ getTextNodes(nodeIn);
+ return textNodes;
+ }
+
parseEmojis() {
twemoji.parse(React.findDOMNode(this), {size: Constants.EMOJI_SIZE});
+ this.getAllChildNodes(React.findDOMNode(this)).forEach((current) => {
+ global.window.emojify.run(current);
+ });
}
+
componentDidMount() {
this.parseEmojis();
}
+
componentDidUpdate() {
this.parseEmojis();
}
+
componentWillReceiveProps(nextProps) {
const linkData = Utils.extractLinks(nextProps.post.message);
this.setState({links: linkData.links, message: linkData.text});
}
+
render() {
const post = this.props.post;
const filenames = this.props.post.filenames;
@@ -75,7 +98,7 @@ export default class PostBody extends React.Component {
comment = (
<p className='post-link'>
<span>
- Commented on {name}{apostrophe} message:
+ {'Commented on '}{name}{apostrophe}{' message:'}
<a
className='theme'
onClick={this.props.handleCommentClick}
@@ -98,7 +121,7 @@ export default class PostBody extends React.Component {
href='#'
onClick={this.props.retryPost}
>
- Retry
+ {'Retry'}
</a>
);
} else if (post.state === Constants.POST_LOADING) {
@@ -133,6 +156,7 @@ export default class PostBody extends React.Component {
{comment}
<p
key={`${post.id}_message`}
+ id={`${post.id}_message`}
className={postClass}
>
{loading}
diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 697fc09c9..87007edcc 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -13,6 +13,7 @@ var SidebarHeader = require('./sidebar_header.jsx');
var SearchBox = require('./search_bar.jsx');
var Constants = require('../utils/constants.jsx');
var NewChannelFlow = require('./new_channel_flow.jsx');
+var UnreadChannelIndicator = require('./unread_channel_indicator.jsx');
export default class Sidebar extends React.Component {
constructor(props) {
@@ -153,6 +154,16 @@ export default class Sidebar extends React.Component {
$(window).on('resize', this.onResize);
}
+ shouldComponentUpdate(nextProps, nextState) {
+ if (!Utils.areStatesEqual(nextProps, this.props)) {
+ return true;
+ }
+
+ if (!Utils.areStatesEqual(nextState, this.state)) {
+ return true;
+ }
+ return false;
+ }
componentDidUpdate() {
this.updateTitle();
this.updateUnreadIndicators();
@@ -274,15 +285,16 @@ export default class Sidebar extends React.Component {
this.updateUnreadIndicators();
}
updateUnreadIndicators() {
- var container = $(React.findDOMNode(this.refs.container));
+ const container = $(React.findDOMNode(this.refs.container));
+
+ var showTopUnread = false;
+ var showBottomUnread = false;
if (this.firstUnreadChannel) {
var firstUnreadElement = $(React.findDOMNode(this.refs[this.firstUnreadChannel]));
if (firstUnreadElement.position().top + firstUnreadElement.height() < 0) {
- $(React.findDOMNode(this.refs.topUnreadIndicator)).css('display', 'initial');
- } else {
- $(React.findDOMNode(this.refs.topUnreadIndicator)).css('display', 'none');
+ showTopUnread = true;
}
}
@@ -290,11 +302,14 @@ export default class Sidebar extends React.Component {
var lastUnreadElement = $(React.findDOMNode(this.refs[this.lastUnreadChannel]));
if (lastUnreadElement.position().top > container.height()) {
- $(React.findDOMNode(this.refs.bottomUnreadIndicator)).css('display', 'initial');
- } else {
- $(React.findDOMNode(this.refs.bottomUnreadIndicator)).css('display', 'none');
+ showBottomUnread = true;
}
}
+
+ this.setState({
+ showTopUnread,
+ showBottomUnread
+ });
}
createChannelElement(channel, index) {
var members = this.state.members;
@@ -432,19 +447,13 @@ export default class Sidebar extends React.Component {
this.lastUnreadChannel = null;
// create elements for all 3 types of channels
- var channelItems = this.state.channels.filter(
- function filterPublicChannels(channel) {
- return channel.type === 'O';
- }
- ).map(this.createChannelElement);
+ const publicChannels = this.state.channels.filter((channel) => channel.type === 'O');
+ const publicChannelItems = publicChannels.map(this.createChannelElement);
- var privateChannelItems = this.state.channels.filter(
- function filterPrivateChannels(channel) {
- return channel.type === 'P';
- }
- ).map(this.createChannelElement);
+ const privateChannels = this.state.channels.filter((channel) => channel.type === 'P');
+ const privateChannelItems = privateChannels.map(this.createChannelElement);
- var directMessageItems = this.state.showDirectChannels.map(this.createChannelElement);
+ const directMessageItems = this.state.showDirectChannels.map(this.createChannelElement);
// update the favicon to show if there are any notifications
var link = document.createElement('link');
@@ -498,20 +507,16 @@ export default class Sidebar extends React.Component {
/>
<SearchBox />
- <div
- ref='topUnreadIndicator'
- className='nav-pills__unread-indicator nav-pills__unread-indicator-top'
- style={{display: 'none'}}
- >
- Unread post(s) above
- </div>
- <div
- ref='bottomUnreadIndicator'
- className='nav-pills__unread-indicator nav-pills__unread-indicator-bottom'
- style={{display: 'none'}}
- >
- Unread post(s) below
- </div>
+ <UnreadChannelIndicator
+ show={this.state.showTopUnread}
+ extraClass='nav-pills__unread-indicator-top'
+ text={'Unread post(s) above'}
+ />
+ <UnreadChannelIndicator
+ show={this.state.showBottomUnread}
+ extraClass='nav-pills__unread-indicator-bottom'
+ text={'Unread post(s) below'}
+ />
<div
ref='container'
@@ -531,7 +536,7 @@ export default class Sidebar extends React.Component {
</a>
</h4>
</li>
- {channelItems}
+ {publicChannelItems}
<li>
<a
href='#'
diff --git a/web/react/components/unread_channel_indicator.jsx b/web/react/components/unread_channel_indicator.jsx
new file mode 100644
index 000000000..12a67633e
--- /dev/null
+++ b/web/react/components/unread_channel_indicator.jsx
@@ -0,0 +1,35 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+// Indicator for the left sidebar which indicate if there's unread posts in a channel that is not shown
+// because it is either above or below the screen
+export default class UnreadChannelIndicator extends React.Component {
+ constructor(props) {
+ super(props);
+ }
+ render() {
+ let displayValue = 'none';
+ if (this.props.show) {
+ displayValue = 'initial';
+ }
+ return (
+ <div
+ className={'nav-pills__unread-indicator ' + this.props.extraClass}
+ style={{display: displayValue}}
+ >
+ {this.props.text}
+ </div>
+ );
+ }
+}
+
+UnreadChannelIndicator.defaultProps = {
+ show: false,
+ extraClass: '',
+ text: ''
+};
+UnreadChannelIndicator.propTypes = {
+ show: React.PropTypes.bool,
+ extraClass: React.PropTypes.string,
+ text: React.PropTypes.string
+};
diff --git a/web/react/components/user_settings_modal.jsx b/web/react/components/user_settings_modal.jsx
index 1daf6ebb9..67a4d0041 100644
--- a/web/react/components/user_settings_modal.jsx
+++ b/web/react/components/user_settings_modal.jsx
@@ -35,7 +35,7 @@ export default class UserSettingsModal extends React.Component {
tabs.push({name: 'security', uiName: 'Security', icon: 'glyphicon glyphicon-lock'});
tabs.push({name: 'notifications', uiName: 'Notifications', icon: 'glyphicon glyphicon-exclamation-sign'});
tabs.push({name: 'appearance', uiName: 'Appearance', icon: 'glyphicon glyphicon-wrench'});
- if (global.window.config.EnableOAuthServiceProvider) {
+ if (global.window.config.EnableOAuthServiceProvider === 'true') {
tabs.push({name: 'developer', uiName: 'Developer', icon: 'glyphicon glyphicon-th'});
}