diff --git a/src/browser/index.jsx b/src/browser/index.jsx
index 481ccdd7..5528d797 100644
--- a/src/browser/index.jsx
+++ b/src/browser/index.jsx
@@ -50,22 +50,31 @@ var MainPage = React.createClass({
});
this.handleOnTeamFocused(key);
},
- handleUnreadCountChange: function(index, unreadCount, mentionCount) {
+ handleUnreadCountChange: function(index, unreadCount, mentionCount, isUnread, isMentioned) {
var unreadCounts = this.state.unreadCounts;
var mentionCounts = this.state.mentionCounts;
+ var unreadAtActive = this.state.unreadAtActive;
+ var mentionAtActive = this.state.mentionAtActive;
unreadCounts[index] = unreadCount;
mentionCounts[index] = mentionCount;
+ // Never turn on the unreadAtActive flag at current focused tab.
+ if (this.state.key !== index || !remote.getCurrentWindow().isFocused()) {
+ unreadAtActive[index] = unreadAtActive[index] || isUnread;
+ mentionAtActive[index] = mentionAtActive[index] || isMentioned;
+ }
this.setState({
unreadCounts: unreadCounts,
- mentionCounts: mentionCounts
+ mentionCounts: mentionCounts,
+ unreadAtActive: unreadAtActive,
+ mentionAtActive: mentionAtActive
});
this.handleUnreadCountTotalChange();
},
- handleUnreadAtActiveChange: function(index, isUnread, isMentioned) {
+ markReadAtActive: function(index) {
var unreadAtActive = this.state.unreadAtActive;
var mentionAtActive = this.state.mentionAtActive;
- unreadAtActive[index] = isUnread;
- mentionAtActive[index] = isMentioned;
+ unreadAtActive[index] = false;
+ mentionAtActive[index] = false;
this.setState({
unreadAtActive: unreadAtActive,
mentionAtActive: mentionAtActive
@@ -93,16 +102,9 @@ var MainPage = React.createClass({
this.props.onUnreadCountChange(allUnreadCount, allMentionCount);
}
},
- handleNotify: function(index, isMentioned) {
- // Never turn on the unreadAtActive flag at current focused tab.
- if (this.state.key === index && remote.getCurrentWindow().isFocused()) {
- return;
- }
- this.handleUnreadAtActiveChange(index, true, isMentioned);
- },
handleOnTeamFocused: function(index) {
// Turn off the flag to indicate whether unread message of active channel contains at current tab.
- this.handleUnreadAtActiveChange(index, false, false);
+ this.markReadAtActive(index);
},
visibleStyle: function(visible) {
@@ -123,24 +125,21 @@ var MainPage = React.createClass({
if (this.props.teams.length > 1) {
tabs_row = (
-
+
);
}
var views = this.props.teams.map(function(team, index) {
- var handleUnreadCountChange = function(unreadCount, mentionCount) {
- thisObj.handleUnreadCountChange(index, unreadCount, mentionCount);
- };
- var handleNotify = function(isMentioned) {
- thisObj.handleNotify(index, isMentioned);
+ var handleUnreadCountChange = function(unreadCount, mentionCount, isUnread, isMentioned) {
+ thisObj.handleUnreadCountChange(index, unreadCount, mentionCount, isUnread, isMentioned);
};
var handleNotificationClick = function() {
thisObj.handleSelect(index);
}
- return ()
+ return ()
});
var views_row = (
{ views }
@@ -158,7 +157,6 @@ var TabBar = React.createClass({
render: function() {
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];
@@ -166,9 +164,19 @@ var TabBar = React.createClass({
if (thisObj.props.unreadAtActive[index]) {
unreadCount += 1;
}
- if (thisObj.props.mentionCounts[index] != 0) {
+
+ var mentionCount = 0;
+ if (thisObj.props.mentionCounts[index] > 0) {
+ mentionCount = thisObj.props.mentionCounts[index];
+ }
+ if (thisObj.props.mentionAtActive[index] === true) {
+ mentionCount += 1;
+ }
+
+ var badge;
+ if (mentionCount != 0) {
badge = (
- { thisObj.props.mentionCounts[index] }
+ { mentionCount }
);
} else if (unreadCount > 0) {
badge = (
@@ -192,23 +200,11 @@ var TabBar = React.createClass({
var MattermostView = React.createClass({
getInitialState: function() {
return {
- unreadCount: 0,
- mentionCount: 0
};
},
- handleUnreadCountChange: function(unreadCount, mentionCount) {
- this.setState({
- unreadCount: unreadCount,
- mentionCount: mentionCount
- });
+ handleUnreadCountChange: function(unreadCount, mentionCount, isUnread, isMentioned) {
if (this.props.onUnreadCountChange) {
- this.props.onUnreadCountChange(unreadCount, mentionCount);
- }
- },
-
- handleNotify: function(isMentioned) {
- if (this.props.onNotify) {
- this.props.onNotify(isMentioned);
+ this.props.onUnreadCountChange(unreadCount, mentionCount, isUnread, isMentioned);
}
},
@@ -260,7 +256,10 @@ var MattermostView = React.createClass({
case 'onUnreadCountChange':
var unreadCount = event.args[0];
var mentionCount = event.args[1];
- thisObj.handleUnreadCountChange(unreadCount, mentionCount);
+ // isUnread and isMentioned is pulse flag.
+ var isUnread = event.args[2];
+ var isMentioned = event.args[3];
+ thisObj.handleUnreadCountChange(unreadCount, mentionCount, isUnread, isMentioned);
break;
case 'onNotificationClick':
thisObj.props.onNotificationClick();
@@ -268,10 +267,6 @@ var MattermostView = React.createClass({
case 'console':
console.log(event.args[0]);
break;
- case 'onActiveChannelNotify':
- var isMentioned = event.args[0];
- thisObj.handleNotify(isMentioned);
- break;
}
});
diff --git a/src/browser/webview/mattermost.js b/src/browser/webview/mattermost.js
index ade81305..d5a5a7d6 100644
--- a/src/browser/webview/mattermost.js
+++ b/src/browser/webview/mattermost.js
@@ -19,18 +19,71 @@ var unreadCountTimer = setInterval(function() {
var elem = document.getElementsByClassName('badge')
var mentionCount = 0;
for (var i = 0; i < elem.length; i++) {
- if (elem[i].offsetHeight != 0) {
+ if (isElementVisible(elem[i])) {
mentionCount++;
}
}
- if (this.unreadCount != unreadCount || this.mentionCount != mentionCount) {
- ipc.sendToHost('onUnreadCountChange', unreadCount, mentionCount);
+ var postAttrName = 'data-reactid';
+ var lastPostElem = document.querySelector('div[' + postAttrName + '="' + lastCheckedPost.reactId + '"]');
+ var isUnread = false;
+ var isMentioned = false;
+ if (lastPostElem === null || !isElementVisible(lastPostElem)) {
+ // When load channel or change channel, lastCheckedPost.reactId is invalid.
+ // So we get latest post and save lastCheckedPost.
+
+ // find active post-list.
+ var postLists = document.querySelectorAll('div.post-list__content');
+ var post;
+ for (var i = 0; i < postLists.length; i++) {
+ if (isElementVisible(postLists[i])) {
+ post = postLists[i].children[0];
+ }
+ }
+
+ // find latest post and save.
+ while (post = post.nextSibling) {
+ if (post.nextSibling === null) {
+ if (post.getAttribute(postAttrName) !== null) {
+ lastCheckedPost.reactId = post.getAttribute(postAttrName);
+ }
+ }
+ }
+ }
+ else if (lastPostElem !== null) {
+ var newPostElem = lastPostElem;
+ while (newPostElem = newPostElem.nextSibling) {
+ lastCheckedPost.reactId = newPostElem.getAttribute(postAttrName);
+ isUnread = true;
+ var activeChannel = document.querySelector('.active .sidebar-channel');
+ var closeButton = activeChannel.getElementsByClassName('btn-close');
+ if (closeButton.length === 1 && closeButton[0].getAttribute('aria-describedby') === 'remove-dm-tooltip') {
+ // If active channel is DM, all posts is treated as menion.
+ isMentioned = true;
+ break;
+ }
+ else {
+ // If active channel is public/private channel, only mentioned post is treated as mention.
+ var highlight = newPostElem.getElementsByClassName('mention-highlight');
+ if (highlight.length != 0 && isElementVisible(highlight[0])) {
+ isMentioned = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (this.unreadCount != unreadCount || this.mentionCount != mentionCount || isUnread || isMentioned) {
+ ipc.sendToHost('onUnreadCountChange', unreadCount, mentionCount, isUnread, isMentioned);
}
this.unreadCount = unreadCount;
this.mentionCount = mentionCount;
}, 1000);
+function isElementVisible(elem) {
+ return elem.offsetHeight !== 0;
+}
+
// On Windows 8.1 and Windows 8, a shortcut with a Application User Model ID must be installed to the Start screen.
// In current version, use tray balloon for notification
function isLowerThanOrEqualWindows8_1() {
@@ -48,12 +101,6 @@ 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');
@@ -61,69 +108,14 @@ function overrideNotificationWithBalloon() {
Notification.prototype.close = function() {};
};
-var lastUnread = {};
+var lastCheckedPost = {
+ reactId: null
+};
// Show window even if it is hidden/minimized when notification is clicked.
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);
-
- // mentionCount for active channel
- var newSeparators = document.getElementsByClassName('new-separator');
- var post;
- var isMentioned = false;
- // Skip until real new-separator appear.
- for (var i = 0; i < newSeparators.length; i++) {
- if (newSeparators[i].offsetParent !== null) {
- post = newSeparators[i];
- }
- }
-
- // If active channel is DM, all posts is treated as menion.
- if (activeChannel === title + "×") {
- isMentioned = true;
- }
- else {
- // If active channel is CHANNEL, only .mention-highlight post is treated as mention.
- if (post != null) {
- // Skip posts until last unread.
- if (activeChannel === title && lastUnread.channel === title && lastUnread.post !== null) {
- var firstPost = post;
- while (post = post.nextSibling) {
- if (lastUnread.post === post.getAttribute('data-reactid')) {
- break;
- }
- }
- // Because last unread post not found, set first post.
- if (post === null) {
- post = firstPost;
- }
- }
-
- while (post = post.nextSibling) {
- var highlight = post.getElementsByClassName('mention-highlight');
- if (highlight.length != 0 && highlight[0].offsetHeight != null) {
- isMentioned = true;
- }
-
- // Remember last unread post.
- if (post.nextSibling === null) {
- lastUnread.post = post.getAttribute('data-reactid');
- lastUnread.channel = title;
- }
- }
- }
- }
-
- // Note: DM title is "{username}×". CHANNEL title is "{channel_title}".
- if (activeChannel === title || activeChannel === title + "×") {
- ipc.sendToHost('onActiveChannelNotify', isMentioned);
- }
};
Notification.requestPermission = function(callback) {
callback('granted');