diff --git a/src/browser/index.jsx b/src/browser/index.jsx index 53d5a15d..60653f18 100644 --- a/src/browser/index.jsx +++ b/src/browser/index.jsx @@ -24,7 +24,8 @@ var MainPage = React.createClass({ return { key: 0, unreadCounts: new Array(this.props.teams.length), - mentionCounts: new Array(this.props.teams.length) + mentionCounts: new Array(this.props.teams.length), + unreadAtActive: new Array(this.props.teams.length) }; }, componentDidMount: function() { @@ -32,6 +33,8 @@ var MainPage = React.createClass({ var focusListener = function() { var webview = document.getElementById('mattermostView' + thisObj.state.key); webview.focus(); + + thisObj.handleOnTeamFocused(thisObj.state.key); }; var currentWindow = remote.getCurrentWindow(); @@ -44,6 +47,7 @@ var MainPage = React.createClass({ this.setState({ key: key }); + this.handleOnTeamFocused(key); }, handleUnreadCountChange: function(index, unreadCount, mentionCount) { var unreadCounts = this.state.unreadCounts; @@ -54,16 +58,44 @@ var MainPage = React.createClass({ unreadCounts: unreadCounts, mentionCounts: mentionCounts }); + this.handleUnreadCountTotalChange(); + }, + handleUnreadAtActiveChange: function(index, state) { + var unreadAtActive = this.state.unreadAtActive; + unreadAtActive[index] = state; + this.setState({ + unreadAtActive: unreadAtActive + }); + this.handleUnreadCountTotalChange(); + }, + handleUnreadCountTotalChange: function() { if (this.props.onUnreadCountChange) { - var allUnreadCount = unreadCounts.reduce(function(prev, curr) { + var allUnreadCount = this.state.unreadCounts.reduce(function(prev, curr) { return prev + curr; + }, 0); + this.state.unreadAtActive.forEach(function(state) { + if (state) { + allUnreadCount += 1; + } }); - var allMentionCount = mentionCounts.reduce(function(prev, curr) { + var allMentionCount = this.state.mentionCounts.reduce(function(prev, curr) { return prev + curr; - }); + }, 0); this.props.onUnreadCountChange(allUnreadCount, allMentionCount); } }, + handleNotify: function(index) { + // Never turn on the unreadAtActive flag at current focused tab. + if (this.state.key === index && remote.getCurrentWindow().isFocused()) { + return; + } + this.handleUnreadAtActiveChange(index, true); + }, + handleOnTeamFocused: function(index) { + // Turn off the flag to indicate whether unread message of active channel contains at current tab. + this.handleUnreadAtActiveChange(index, false); + }, + visibleStyle: function(visible) { var visibility = visible ? 'visible' : 'hidden'; return { @@ -82,7 +114,8 @@ var MainPage = React.createClass({ if (this.props.teams.length > 1) { tabs_row = ( - + ); } @@ -91,11 +124,14 @@ var MainPage = React.createClass({ var handleUnreadCountChange = function(unreadCount, mentionCount) { thisObj.handleUnreadCountChange(index, unreadCount, mentionCount); }; + var handleNotify = function() { + thisObj.handleNotify(index); + }; var handleNotificationClick = function() { thisObj.handleSelect(index); } - return () + return () }); var views_row = ( { views } @@ -114,11 +150,18 @@ var TabBar = React.createClass({ var thisObj = this; var tabs = this.props.teams.map(function(team, index) { var badge; + var unreadCount = 0; + if (thisObj.props.unreadCounts[index] > 0) { + unreadCount = thisObj.props.unreadCounts[index]; + } + if (thisObj.props.unreadAtActive[index]) { + unreadCount += 1; + } if (thisObj.props.mentionCounts[index] != 0) { badge = ( { thisObj.props.mentionCounts[index] } ); - } else if (thisObj.props.unreadCounts[index] != 0) { + } else if (unreadCount > 0) { badge = (); @@ -140,7 +183,8 @@ var TabBar = React.createClass({ var MattermostView = React.createClass({ getInitialState: function() { return { - unreadCount: 0 + unreadCount: 0, + mentionCount: 0 }; }, handleUnreadCountChange: function(unreadCount, mentionCount) { @@ -152,6 +196,13 @@ var MattermostView = React.createClass({ this.props.onUnreadCountChange(unreadCount, mentionCount); } }, + + handleNotify: function() { + if (this.props.onNotify) { + this.props.onNotify(); + } + }, + componentDidMount: function() { var thisObj = this; var webview = ReactDOM.findDOMNode(this.refs.webview); @@ -208,6 +259,9 @@ var MattermostView = React.createClass({ case 'console': console.log(event.args[0]); break; + case 'onActiveChannelNotify': + thisObj.handleNotify(); + break; } }); diff --git a/src/browser/webview/mattermost.js b/src/browser/webview/mattermost.js index 37becb4d..9dcb088b 100644 --- a/src/browser/webview/mattermost.js +++ b/src/browser/webview/mattermost.js @@ -13,6 +13,7 @@ var unreadCountTimer = setInterval(function() { } // unreadCount in sidebar + // Note: the active channel doesn't have '.unread-title'. var unreadCount = document.getElementsByClassName('unread-title').length; // mentionCount in sidebar var elem = document.getElementsByClassName('badge') @@ -28,7 +29,6 @@ var unreadCountTimer = setInterval(function() { var post; for (var i = 0; i < newSeparators.length; i++) { if (newSeparators[i].offsetParent !== null) { - unreadCount += 1; post = newSeparators[i]; } } @@ -67,6 +67,12 @@ function overrideNotificationWithBalloon() { title: title, options: options }); + + // Send notification event at active channel. + var activeChannel = document.querySelector('.active .sidebar-channel').text; + if (activeChannel === title) { + ipc.sendToHost('onActiveChannelNotify'); + } }; Notification.requestPermission = function(callback) { callback('granted'); @@ -78,6 +84,14 @@ function overrideNotificationWithBalloon() { function overrideNotification() { Notification = function(title, options) { this.notification = new NativeNotification(title, options); + + // Send notification event at active channel. + var activeChannel = document.querySelector('.active .sidebar-channel').text; + console.log(activeChannel); + console.log(title); + if (activeChannel === title) { + ipc.sendToHost('onActiveChannelNotify'); + } }; Notification.requestPermission = function(callback) { callback('granted');