summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorhmhealey <harrisonmhealey@gmail.com>2015-09-15 17:36:48 -0400
committerhmhealey <harrisonmhealey@gmail.com>2015-09-16 16:51:16 -0400
commit7e66a3d5be9a928b39c22756a5d83703b99648c4 (patch)
treecedc5f20c67b89b3ec11d97953b835f215a95ce6 /web
parent8d0c69aec62a0b48db353f40769d3c4baded8e87 (diff)
downloadchat-7e66a3d5be9a928b39c22756a5d83703b99648c4.tar.gz
chat-7e66a3d5be9a928b39c22756a5d83703b99648c4.tar.bz2
chat-7e66a3d5be9a928b39c22756a5d83703b99648c4.zip
Moved unread channel indicators into their own React component and file
Diffstat (limited to 'web')
-rw-r--r--web/react/components/sidebar.jsx89
-rw-r--r--web/react/components/unread_channel_indicators.jsx93
2 files changed, 112 insertions, 70 deletions
diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx
index 370250e4a..a16a0a8bb 100644
--- a/web/react/components/sidebar.jsx
+++ b/web/react/components/sidebar.jsx
@@ -11,6 +11,7 @@ var BrowserStore = require('../stores/browser_store.jsx');
var Utils = require('../utils/utils.jsx');
var SidebarHeader = require('./sidebar_header.jsx');
var SearchBox = require('./search_bar.jsx');
+var UnreadChannelIndicators = require('./unread_channel_indicators.jsx');
var Constants = require('../utils/constants.jsx');
var NewChannelFlow = require('./new_channel_flow.jsx');
@@ -19,13 +20,10 @@ export default class Sidebar extends React.Component {
super(props);
this.badgesActive = false;
- this.firstUnreadChannel = null;
- this.lastUnreadChannel = null;
this.onChange = this.onChange.bind(this);
this.onScroll = this.onScroll.bind(this);
this.onResize = this.onResize.bind(this);
- this.updateUnreadIndicators = this.updateUnreadIndicators.bind(this);
this.createChannelElement = this.createChannelElement.bind(this);
this.state = this.getStateFromStores();
@@ -149,13 +147,13 @@ export default class Sidebar extends React.Component {
$('.nav-pills__container').perfectScrollbar();
this.updateTitle();
- this.updateUnreadIndicators();
+ this.refs.unreadIndicators.onParentUpdate(this.refs);
$(window).on('resize', this.onResize);
}
componentDidUpdate() {
this.updateTitle();
- this.updateUnreadIndicators();
+ this.refs.unreadIndicators.onParentUpdate(this.refs);
}
componentWillUnmount() {
$(window).off('resize', this.onResize);
@@ -268,41 +266,12 @@ export default class Sidebar extends React.Component {
}
}
onScroll() {
- this.updateUnreadIndicators();
+ this.refs.unreadIndicators.onParentUpdate(this.refs);
}
onResize() {
- this.updateUnreadIndicators();
+ this.refs.unreadIndicators.onParentUpdate(this.refs);
}
- updateUnreadIndicators() {
- const container = $(React.findDOMNode(this.refs.container));
- const topUnreadIndicator = $(React.findDOMNode(this.refs.topUnreadIndicator));
- const bottomUnreadIndicator = $(React.findDOMNode(this.refs.bottomUnreadIndicator));
-
- if (this.firstUnreadChannel) {
- var firstUnreadElement = $(React.findDOMNode(this.refs[this.firstUnreadChannel]));
-
- if (firstUnreadElement.position().top + firstUnreadElement.height() < 0) {
- topUnreadIndicator.css('display', 'initial');
- } else {
- topUnreadIndicator.css('display', 'none');
- }
- } else {
- topUnreadIndicator.css('display', 'none');
- }
-
- if (this.lastUnreadChannel) {
- var lastUnreadElement = $(React.findDOMNode(this.refs[this.lastUnreadChannel]));
-
- if (lastUnreadElement.position().top > container.height()) {
- bottomUnreadIndicator.css('display', 'initial');
- } else {
- bottomUnreadIndicator.css('display', 'none');
- }
- } else {
- bottomUnreadIndicator.css('display', 'none');
- }
- }
- createChannelElement(channel, index) {
+ createChannelElement(unreadChannels, channel, index) {
var members = this.state.members;
var activeId = this.state.activeId;
var channelMember = members[channel.id];
@@ -324,10 +293,7 @@ export default class Sidebar extends React.Component {
titleClass = 'unread-title';
if (channel.id !== activeId) {
- if (!this.firstUnreadChannel) {
- this.firstUnreadChannel = channel.name;
- }
- this.lastUnreadChannel = channel.name;
+ unreadChannels.push(channel);
}
}
@@ -433,24 +399,17 @@ export default class Sidebar extends React.Component {
render() {
this.badgesActive = false;
- // keep track of the first and last unread channels so we can use them to set the unread indicators
- this.firstUnreadChannel = null;
- this.lastUnreadChannel = null;
+ // keep track of unread channels so we can use them to set the unread indicators
+ const unreadChannels = [];
// 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.bind(this, unreadChannels));
- 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.bind(this, unreadChannels));
- var directMessageItems = this.state.showDirectChannels.map(this.createChannelElement);
+ const directMessageItems = this.state.showDirectChannels.map(this.createChannelElement.bind(this, unreadChannels));
// update the favicon to show if there are any notifications
var link = document.createElement('link');
@@ -504,20 +463,10 @@ 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>
+ <UnreadChannelIndicators
+ ref='unreadIndicators'
+ unreadChannels={unreadChannels}
+ />
<div
ref='container'
@@ -537,7 +486,7 @@ export default class Sidebar extends React.Component {
</a>
</h4>
</li>
- {channelItems}
+ {publicChannelItems}
<li>
<a
href='#'
diff --git a/web/react/components/unread_channel_indicators.jsx b/web/react/components/unread_channel_indicators.jsx
new file mode 100644
index 000000000..852e0dbb7
--- /dev/null
+++ b/web/react/components/unread_channel_indicators.jsx
@@ -0,0 +1,93 @@
+// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+// Indicators 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 UnreadChannelIndicators extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.getFirstLastUnreadChannels = this.getFirstLastUnreadChannels.bind(this);
+ this.onParentUpdate = this.onParentUpdate.bind(this);
+
+ this.state = this.getFirstLastUnreadChannels(props);
+ }
+
+ getFirstLastUnreadChannels(props) {
+ let firstUnreadChannel = null;
+ let lastUnreadChannel = null;
+
+ for (const unreadChannel of props.unreadChannels) {
+ if (!firstUnreadChannel) {
+ firstUnreadChannel = unreadChannel;
+ }
+ lastUnreadChannel = unreadChannel;
+ }
+
+ return {
+ firstUnreadChannel,
+ lastUnreadChannel
+ };
+ }
+
+ onParentUpdate(parentRefs) {
+ const container = $(React.findDOMNode(parentRefs.container));
+ const topUnreadIndicator = $(React.findDOMNode(this.refs.topIndicator));
+ const bottomUnreadIndicator = $(React.findDOMNode(this.refs.bottomIndicator));
+
+ if (this.state.firstUnreadChannel) {
+ var firstUnreadElement = $(React.findDOMNode(parentRefs[this.state.firstUnreadChannel.name]));
+
+ if (firstUnreadElement.position().top + firstUnreadElement.height() < 0) {
+ topUnreadIndicator.css('display', 'initial');
+ } else {
+ topUnreadIndicator.css('display', 'none');
+ }
+ } else {
+ topUnreadIndicator.css('display', 'none');
+ }
+
+ if (this.state.lastUnreadChannel) {
+ var lastUnreadElement = $(React.findDOMNode(parentRefs[this.state.lastUnreadChannel.name]));
+
+ if (lastUnreadElement.position().top > container.height()) {
+ bottomUnreadIndicator.css('display', 'initial');
+ } else {
+ bottomUnreadIndicator.css('display', 'none');
+ }
+ } else {
+ bottomUnreadIndicator.css('display', 'none');
+ }
+ }
+
+ componentWillReceiveProps(nextProps) {
+ this.setState(this.getFirstLastUnreadChannels(nextProps));
+ }
+
+ render() {
+ return (
+ <div>
+ <div
+ ref='topIndicator'
+ className='nav-pills__unread-indicator nav-pills__unread-indicator-top'
+ style={{display: 'none'}}
+ >
+ {'Unread post(s) above'}
+ </div>
+ <div
+ ref='bottomIndicator'
+ className='nav-pills__unread-indicator nav-pills__unread-indicator-bottom'
+ style={{display: 'none'}}
+ >
+ {'Unread post(s) below'}
+ </div>
+ </div>
+ );
+ }
+}
+
+UnreadChannelIndicators.propTypes = {
+
+ // a list of the unread channels displayed in the parent
+ unreadChannels: React.PropTypes.array.isRequired
+};