diff --git a/src/browser/index.jsx b/src/browser/index.jsx index 43790a6b..65e1ebc5 100644 --- a/src/browser/index.jsx +++ b/src/browser/index.jsx @@ -23,7 +23,8 @@ var MainPage = React.createClass({ getInitialState: function() { return { key: 0, - unreadCounts: new Array(this.props.teams.length) + unreadCounts: new Array(this.props.teams.length), + unreadAtActive: new Array(this.props.teams.length) }; }, componentDidMount: function() { @@ -31,6 +32,8 @@ var MainPage = React.createClass({ var focusListener = function() { var webview = document.getElementById('mattermostView' + thisObj.state.key); webview.focus(); + + this.handleOnTeamFocused(key); }; var currentWindow = remote.getCurrentWindow(); @@ -43,6 +46,7 @@ var MainPage = React.createClass({ this.setState({ key: key }); + this.handleOnTeamFocused(key); }, handleUnreadCountChange: function(index, count) { var counts = this.state.unreadCounts; @@ -50,13 +54,41 @@ var MainPage = React.createClass({ this.setState({ unreadCounts: counts }); + 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 c = counts.reduce(function(prev, curr) { + var c = this.state.unreadCounts.reduce(function(prev, curr) { return prev + curr; + }, 0); + this.state.unreadAtActive.forEach(function(state) { + if (state) { + c += 1; + } }); this.props.onUnreadCountChange(c); } }, + handleNotify: function(index) { + // Never turn on the unreadAtActive flag at current focused tab. + if (state && 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 { @@ -75,7 +107,7 @@ var MainPage = React.createClass({ if (this.props.teams.length > 1) { tabs_row = ( - + ); } @@ -84,10 +116,13 @@ var MainPage = React.createClass({ var handleUnreadCountChange = function(count) { thisObj.handleUnreadCountChange(index, count); }; + var handleNotify = function() { + thisObj.handleNotify(index); + }; var handleNotificationClick = function() { thisObj.handleSelect(index); } - return () }); var views_row = ( @@ -107,9 +142,16 @@ var TabBar = React.createClass({ var thisObj = this; var tabs = this.props.teams.map(function(team, index) { var badge; - if (thisObj.props.unreadCounts[index] != 0) { + var unreadCount = 0; + if (thisObj.props.unreadCounts[index] > 0) { + unreadCount = thisObj.props.unreadCounts[index]; + } + if (thisObj.props.unreadAtActive[index]) { + unreadCount += 1; + } + if (unreadCount > 0) { badge = ( - { thisObj.props.unreadCounts[index] } + { unreadCount } ); } return ( @@ -127,19 +169,18 @@ var TabBar = React.createClass({ }); var MattermostView = React.createClass({ - getInitialState: function() { - return { - unreadCount: 0 - }; - }, handleUnreadCountChange: function(count) { - this.setState({ - unreadCount: count - }); if (this.props.onUnreadCountChange) { this.props.onUnreadCountChange(count); } }, + + handleNotify: function() { + if (this.props.onNotify) { + this.props.onNotify(); + } + }, + componentDidMount: function() { var thisObj = this; var webview = ReactDOM.findDOMNode(this.refs.webview); @@ -191,9 +232,12 @@ var MattermostView = React.createClass({ break; case 'onNotificationClick': thisObj.props.onNotificationClick(); + break; + case 'onActiveChannelNotify': + thisObj.handleNotify(); + break; } }); - }, render: function() { // 'disablewebsecurity' is necessary to display external images. diff --git a/src/browser/webview/mattermost.js b/src/browser/webview/mattermost.js index 4620f9f6..20af7a44 100644 --- a/src/browser/webview/mattermost.js +++ b/src/browser/webview/mattermost.js @@ -10,18 +10,8 @@ var unreadCountTimer = setInterval(function() { } // count in sidebar + // Note: the active channel doesn't have '.unread-title'. var unreadCount = document.getElementsByClassName('unread-title').length; - - // count for active channel - if(!electron.remote.getCurrentWindow().isFocused()) { - var newSeparators = document.getElementsByClassName('new-separator'); - for (var i = 0; i < newSeparators.length; i++) { - if (newSeparators[i].offsetParent !== null) { - unreadCount += 1; - } - } - } - if (this.count != unreadCount) { ipc.sendToHost('onUnreadCountChange', unreadCount); } @@ -45,6 +35,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'); @@ -56,6 +52,12 @@ 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; + if (activeChannel === title) { + ipc.sendToHost('onActiveChannelNotify'); + } }; Notification.requestPermission = function(callback) { callback('granted');