Bug 1551590 - OTR: improve notifications when a chat starts with a verification request. r=kaie
This commit is contained in:
Родитель
87e443fdb0
Коммит
d45e4b377e
|
@ -18,6 +18,11 @@ interface imIConversation: prplIConversation {
|
|||
// Note: this will not be logged.
|
||||
void systemMessage(in AUTF8String aMessage, [optional] in boolean aIsError);
|
||||
|
||||
// Write a system message into the conversation and trigger the udpate of the
|
||||
// notification counter during an off-the-record authentication request.
|
||||
// Note: this will not be logged.
|
||||
void notificationOTR(in AUTF8String aMessage);
|
||||
|
||||
attribute prplIConversation target;
|
||||
|
||||
// Number of unread messages (all messages, including system
|
||||
|
@ -29,6 +34,8 @@ interface imIConversation: prplIConversation {
|
|||
// Number of unread incoming messages (both targeted and untargeted
|
||||
// messages are counted).
|
||||
readonly attribute unsigned long unreadIncomingMessageCount;
|
||||
// Number of unread off-the-record authentication requests.
|
||||
readonly attribute unsigned long unreadOTRNotificationCount;
|
||||
// Reset all unread message counts.
|
||||
void markAsRead();
|
||||
|
||||
|
|
|
@ -249,10 +249,15 @@ UIConversation.prototype = {
|
|||
get unreadIncomingMessageCount() {
|
||||
return this._unreadIncomingMessageCount;
|
||||
},
|
||||
_unreadOTRNotificationCount: 0,
|
||||
get unreadOTRNotificationCount() {
|
||||
return this._unreadOTRNotificationCount;
|
||||
},
|
||||
markAsRead() {
|
||||
delete this._unreadMessageCount;
|
||||
delete this._unreadTargetedMessageCount;
|
||||
delete this._unreadIncomingMessageCount;
|
||||
delete this._unreadOTRNotificationCount;
|
||||
this._notifyUnreadCountChanged();
|
||||
},
|
||||
_lastNotifiedUnreadCount: 0,
|
||||
|
@ -445,6 +450,18 @@ UIConversation.prototype = {
|
|||
new Message("system", aText, flags).conversation = this;
|
||||
},
|
||||
|
||||
notificationOTR(aText) {
|
||||
this._unreadOTRNotificationCount++;
|
||||
this.systemMessage(aText);
|
||||
for (let observer of this._observers) {
|
||||
observer.observe(
|
||||
this,
|
||||
"unread-message-count-changed",
|
||||
this._unreadOTRNotificationCount.toString()
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
// prplIConversation
|
||||
get isChat() {
|
||||
return this.target.isChat;
|
||||
|
|
|
@ -169,6 +169,13 @@ var otrAuth = {
|
|||
if (mode === "ask") {
|
||||
let context = OTR.getContext(uiConv.target);
|
||||
OTR.abortSMP(context);
|
||||
// Close the ask-auth notification if it was previously triggered.
|
||||
OTR.notifyObservers(
|
||||
{
|
||||
context,
|
||||
},
|
||||
"otr:cancel-ask-auth"
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -61,6 +61,10 @@ state-unverified-label = Unverified
|
|||
state-private-label = Private
|
||||
state-finished-label = Finished
|
||||
|
||||
# Variables:
|
||||
# $name (String) - the screen name of a chat contact person
|
||||
verify-request = { $name } requested the verification of your identity.
|
||||
|
||||
# Variables:
|
||||
# $name (String) - the screen name of a chat contact person
|
||||
afterauth-private = You have verified the identity of { $name }.
|
||||
|
|
|
@ -257,6 +257,7 @@ var OTRUI = {
|
|||
}
|
||||
|
||||
this.enabled = true;
|
||||
this.notificationbox = null;
|
||||
|
||||
OTR.addObserver(OTRUI);
|
||||
OTR.loadFiles()
|
||||
|
@ -479,9 +480,52 @@ var OTRUI = {
|
|||
return;
|
||||
}
|
||||
|
||||
let window = this.globalDoc.defaultView;
|
||||
let name = uiConv.target.normalizedName;
|
||||
OTRUI.openAuth(window, name, "ask", uiConv, aObject);
|
||||
let msg = _strArgs("verify-request", { name });
|
||||
// Trigger the udpate of the unread message counter.
|
||||
uiConv.notificationOTR(msg);
|
||||
Services.obs.notifyObservers(uiConv, "new-otr-verification-request");
|
||||
|
||||
// Trigger the inline notification.
|
||||
let window = this.globalDoc.defaultView;
|
||||
let buttons = [
|
||||
{
|
||||
label: _str("finger-verify"),
|
||||
accessKey: _str("finger-verify-accessKey"),
|
||||
callback() {
|
||||
OTRUI.openAuth(window, name, "ask", uiConv, aObject);
|
||||
// prevent closing of notification bar when the button is hit
|
||||
return true;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
let mainWindow = Services.wm.getMostRecentWindow("mail:3pane");
|
||||
this.notificationbox = mainWindow.chatHandler.msgNotificationBar;
|
||||
|
||||
let priority = this.globalBox.PRIORITY_WARNING_MEDIUM;
|
||||
this.notificationbox.appendNotification(
|
||||
msg,
|
||||
name,
|
||||
null,
|
||||
priority,
|
||||
buttons,
|
||||
null
|
||||
);
|
||||
},
|
||||
|
||||
closeAskAuthNotification(aObject) {
|
||||
if (!this.notificationbox) {
|
||||
return;
|
||||
}
|
||||
|
||||
let name = aObject.context.username;
|
||||
let notification = this.notificationbox.getNotificationWithValue(name);
|
||||
if (!notification) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.notificationbox.removeNotification(notification);
|
||||
},
|
||||
|
||||
closeUnverified(context) {
|
||||
|
@ -630,7 +674,7 @@ var OTRUI = {
|
|||
}
|
||||
},
|
||||
|
||||
notifyVerification(context, key, cancelable) {
|
||||
notifyVerification(context, key, cancelable, verifiable) {
|
||||
let uiConv = OTR.getUIConvFromContext(context);
|
||||
if (!uiConv) {
|
||||
return;
|
||||
|
@ -656,6 +700,23 @@ var OTRUI = {
|
|||
];
|
||||
}
|
||||
|
||||
if (verifiable) {
|
||||
let window = this.globalDoc.defaultView;
|
||||
|
||||
buttons = [
|
||||
{
|
||||
label: _str("finger-verify"),
|
||||
accessKey: _str("finger-verify-accessKey"),
|
||||
callback() {
|
||||
let name = uiConv.target.normalizedName;
|
||||
OTRUI.openAuth(window, name, "start", uiConv);
|
||||
// prevent closing of notification bar when the button is hit
|
||||
return true;
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// higher priority to overlay the current notifyUnverified
|
||||
let priority = this.globalBox.PRIORITY_WARNING_HIGH;
|
||||
OTRUI.closeUnverified(context);
|
||||
|
@ -675,15 +736,17 @@ var OTRUI = {
|
|||
// let uiConv = OTR.getUIConvFromContext(aObj.context);
|
||||
if (!aObj.progress) {
|
||||
OTRUI.closeAuth(aObj.context);
|
||||
OTRUI.notifyVerification(aObj.context, "otr:auth-error", false);
|
||||
OTRUI.notifyVerification(aObj.context, "otr:auth-error", false, false);
|
||||
} else if (aObj.progress === 100) {
|
||||
let key;
|
||||
let verifiable = false;
|
||||
if (aObj.success) {
|
||||
if (aObj.context.trust) {
|
||||
key = "otr:auth-success";
|
||||
OTR.notifyTrust(aObj.context);
|
||||
} else {
|
||||
key = "otr:auth-successThem";
|
||||
verifiable = true;
|
||||
}
|
||||
} else {
|
||||
key = "otr:auth-fail";
|
||||
|
@ -691,12 +754,13 @@ var OTRUI = {
|
|||
OTR.notifyTrust(aObj.context);
|
||||
}
|
||||
}
|
||||
OTRUI.notifyVerification(aObj.context, key, false);
|
||||
OTRUI.notifyVerification(aObj.context, key, false, verifiable);
|
||||
} else {
|
||||
// TODO: show the aObj.progress to the user with a
|
||||
// <progressmeter mode="determined" value="10" />
|
||||
OTRUI.notifyVerification(aObj.context, "otr:auth-waiting", true);
|
||||
OTRUI.notifyVerification(aObj.context, "otr:auth-waiting", true, false);
|
||||
}
|
||||
OTRUI.closeAskAuthNotification(aObj);
|
||||
},
|
||||
|
||||
onAccountCreated(acc) {
|
||||
|
@ -829,6 +893,9 @@ var OTRUI = {
|
|||
case "otr:auth-update":
|
||||
OTRUI.updateAuth(aObject);
|
||||
break;
|
||||
case "otr:cancel-ask-auth":
|
||||
OTRUI.closeAskAuthNotification(aObject);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -82,8 +82,7 @@
|
|||
</stack>
|
||||
</hbox>
|
||||
<hbox class="otr-container"
|
||||
align="start"
|
||||
valign="middle"
|
||||
align="middle"
|
||||
hidden="true">
|
||||
<label class="otr-label"
|
||||
crop="end"
|
||||
|
|
|
@ -173,15 +173,11 @@
|
|||
this.setAttribute("flex", "1");
|
||||
this.classList.add("convBox");
|
||||
|
||||
this.convTop = document.createXULElement("hbox");
|
||||
this.convTop = document.createXULElement("vbox");
|
||||
this.convTop.setAttribute("flex", "1");
|
||||
this.convTop.classList.add("conv-top");
|
||||
|
||||
this.notification = document.createXULElement("hbox");
|
||||
this.notification.setAttribute("flex", "1");
|
||||
|
||||
let nbox = document.createXULElement("vbox");
|
||||
nbox.setAttribute("flex", "1");
|
||||
this.notification = document.createXULElement("vbox");
|
||||
|
||||
this.convBrowser = document.createXULElement("browser", {
|
||||
is: "conversation-browser",
|
||||
|
@ -198,11 +194,10 @@
|
|||
this.findbar = document.createXULElement("findbar");
|
||||
this.findbar.setAttribute("reversed", "true");
|
||||
|
||||
nbox.appendChild(this.convBrowser);
|
||||
nbox.appendChild(this.progressBar);
|
||||
nbox.appendChild(this.findbar);
|
||||
this.notification.appendChild(nbox);
|
||||
this.convTop.appendChild(this.notification);
|
||||
this.convTop.appendChild(this.convBrowser);
|
||||
this.convTop.appendChild(this.progressBar);
|
||||
this.convTop.appendChild(this.findbar);
|
||||
|
||||
this.splitter = document.createXULElement("splitter");
|
||||
this.splitter.setAttribute("orient", "vertical");
|
||||
|
@ -295,15 +290,15 @@
|
|||
}
|
||||
|
||||
get msgNotificationBar() {
|
||||
delete this.msgNotificationBar;
|
||||
delete this._msgNotificationBar;
|
||||
|
||||
let newNotificationBox = new MozElements.NotificationBox(element => {
|
||||
element.setAttribute("flex", "1");
|
||||
element.setAttribute("notificationside", "top");
|
||||
this.notification.append(element);
|
||||
this.notification.prepend(element);
|
||||
});
|
||||
|
||||
return (this.msgNotificationBar = newNotificationBox);
|
||||
return (this._msgNotificationBar = newNotificationBox);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
|
|
|
@ -170,7 +170,9 @@
|
|||
this.removeAttribute("unread");
|
||||
this.removeAttribute("attention");
|
||||
} else {
|
||||
let unreadCount = this.conv.unreadIncomingMessageCount;
|
||||
let unreadCount =
|
||||
this.conv.unreadIncomingMessageCount +
|
||||
this.conv.unreadOTRNotificationCount;
|
||||
let directedMessages = unreadCount;
|
||||
if (unreadCount) {
|
||||
this.setAttribute("unread", "true");
|
||||
|
|
|
@ -407,14 +407,14 @@ var chatTabType = {
|
|||
|
||||
var chatHandler = {
|
||||
get msgNotificationBar() {
|
||||
delete this.msgNotificationBar;
|
||||
delete this._msgNotificationBar;
|
||||
|
||||
let newNotificationBox = new MozElements.NotificationBox(element => {
|
||||
element.setAttribute("notificationside", "top");
|
||||
document.getElementById("chat-notification-top").prepend(element);
|
||||
});
|
||||
|
||||
return (this.msgNotificationBar = newNotificationBox);
|
||||
return (this._msgNotificationBar = newNotificationBox);
|
||||
},
|
||||
|
||||
_addConversation(aConv) {
|
||||
|
@ -476,26 +476,32 @@ var chatHandler = {
|
|||
return;
|
||||
}
|
||||
|
||||
let [unreadTargettedCount, unreadTotalCount] = this.countUnreadMessages();
|
||||
chatButton.badgeCount = unreadTargettedCount;
|
||||
let [
|
||||
unreadTargettedCount,
|
||||
unreadTotalCount,
|
||||
unreadOTRNotificationCount,
|
||||
] = this.countUnreadMessages();
|
||||
let unreadMsgAndNotificationCount =
|
||||
unreadTargettedCount + unreadOTRNotificationCount;
|
||||
chatButton.badgeCount = unreadMsgAndNotificationCount;
|
||||
|
||||
if (unreadTotalCount) {
|
||||
if (unreadTotalCount || unreadOTRNotificationCount) {
|
||||
chatButton.setAttribute("unreadMessages", "true");
|
||||
} else {
|
||||
chatButton.removeAttribute("unreadMessages");
|
||||
}
|
||||
|
||||
if (unreadTargettedCount != this._notifiedUnreadCount) {
|
||||
if (unreadMsgAndNotificationCount != this._notifiedUnreadCount) {
|
||||
let unreadInt = Cc["@mozilla.org/supports-PRInt32;1"].createInstance(
|
||||
Ci.nsISupportsPRInt32
|
||||
);
|
||||
unreadInt.data = unreadTargettedCount;
|
||||
unreadInt.data = unreadMsgAndNotificationCount;
|
||||
Services.obs.notifyObservers(
|
||||
unreadInt,
|
||||
"unread-im-count-changed",
|
||||
unreadTargettedCount
|
||||
unreadMsgAndNotificationCount
|
||||
);
|
||||
this._notifiedUnreadCount = unreadTargettedCount;
|
||||
this._notifiedUnreadCount = unreadMsgAndNotificationCount;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -503,11 +509,13 @@ var chatHandler = {
|
|||
let convs = imServices.conversations.getUIConversations();
|
||||
let unreadTargettedCount = 0;
|
||||
let unreadTotalCount = 0;
|
||||
let unreadOTRNotificationCount = 0;
|
||||
for (let conv of convs) {
|
||||
unreadTargettedCount += conv.unreadTargetedMessageCount;
|
||||
unreadTotalCount += conv.unreadIncomingMessageCount;
|
||||
unreadOTRNotificationCount += conv.unreadOTRNotificationCount;
|
||||
}
|
||||
return [unreadTargettedCount, unreadTotalCount];
|
||||
return [unreadTargettedCount, unreadTotalCount, unreadOTRNotificationCount];
|
||||
},
|
||||
|
||||
updateTitle() {
|
||||
|
|
|
@ -45,13 +45,13 @@ var gAccountManager = {
|
|||
_connectedLabelInterval: 0,
|
||||
|
||||
get msgNotificationBar() {
|
||||
delete this.msgNotificationBar;
|
||||
delete this._msgNotificationBar;
|
||||
|
||||
let newNotificationBox = new MozElements.NotificationBox(element => {
|
||||
document.getElementById("accounts-notification-box").prepend(element);
|
||||
});
|
||||
|
||||
return (this.msgNotificationBar = newNotificationBox);
|
||||
return (this._msgNotificationBar = newNotificationBox);
|
||||
},
|
||||
|
||||
load() {
|
||||
|
|
|
@ -189,62 +189,80 @@ var Notifications = {
|
|||
},
|
||||
|
||||
init() {
|
||||
Services.obs.addObserver(Notifications, "new-otr-verification-request");
|
||||
Services.obs.addObserver(Notifications, "new-directed-incoming-message");
|
||||
Services.obs.addObserver(Notifications, "alertclickcallback");
|
||||
},
|
||||
|
||||
_notificationPrefName: "mail.chat.show_desktop_notifications",
|
||||
observe(aSubject, aTopic, aData) {
|
||||
if (
|
||||
aTopic == "new-directed-incoming-message" &&
|
||||
Services.prefs.getBoolPref(this._notificationPrefName)
|
||||
) {
|
||||
// If this is the first message, we show the notification and
|
||||
// store the sender's name.
|
||||
let sender = aSubject.who || aSubject.alias;
|
||||
if (this._lastMessageSender == null) {
|
||||
this._lastMessageSender = sender;
|
||||
this._lastMessageTime = aSubject.time;
|
||||
this._showMessageNotification(aSubject);
|
||||
} else if (
|
||||
this._lastMessageSender != sender ||
|
||||
aSubject.time > this._lastMessageTime + kTimeToWaitForMoreMsgs
|
||||
) {
|
||||
// If the sender is not the same as the previous sender or the
|
||||
// time elapsed since the last message is greater than kTimeToWaitForMoreMsgs,
|
||||
// we show the held notification and set timeout for the message just arrived.
|
||||
if (this._heldMessage) {
|
||||
// if the time for the current message is greater than _lastMessageTime by
|
||||
// more than kTimeToWaitForMoreMsgs, this will not happen since the notification will
|
||||
// have already been dispatched.
|
||||
if (!Services.prefs.getBoolPref(this._notificationPrefName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (aTopic) {
|
||||
case "new-directed-incoming-message":
|
||||
// If this is the first message, we show the notification and
|
||||
// store the sender's name.
|
||||
let sender = aSubject.who || aSubject.alias;
|
||||
if (this._lastMessageSender == null) {
|
||||
this._lastMessageSender = sender;
|
||||
this._lastMessageTime = aSubject.time;
|
||||
this._showMessageNotification(aSubject);
|
||||
} else if (
|
||||
this._lastMessageSender != sender ||
|
||||
aSubject.time > this._lastMessageTime + kTimeToWaitForMoreMsgs
|
||||
) {
|
||||
// If the sender is not the same as the previous sender or the
|
||||
// time elapsed since the last message is greater than kTimeToWaitForMoreMsgs,
|
||||
// we show the held notification and set timeout for the message just arrived.
|
||||
if (this._heldMessage) {
|
||||
// if the time for the current message is greater than _lastMessageTime by
|
||||
// more than kTimeToWaitForMoreMsgs, this will not happen since the notification will
|
||||
// have already been dispatched.
|
||||
clearTimeout(this._timeoutId);
|
||||
this._showMessageNotification(this._heldMessage, this._msgCounter);
|
||||
}
|
||||
this._lastMessageSender = sender;
|
||||
this._lastMessageTime = aSubject.time;
|
||||
this._showMessageNotification(aSubject);
|
||||
} else if (
|
||||
this._lastMessageSender == sender &&
|
||||
this._lastMessageTime + kTimeToWaitForMoreMsgs >= aSubject.time
|
||||
) {
|
||||
// If the sender is same as the previous sender and the time elapsed since the
|
||||
// last held message is less than kTimeToWaitForMoreMsgs, we increase the held messages
|
||||
// counter and update the last message's arrival time.
|
||||
this._lastMessageTime = aSubject.time;
|
||||
if (!this._heldMessage) {
|
||||
this._heldMessage = aSubject;
|
||||
} else {
|
||||
this._msgCounter++;
|
||||
}
|
||||
|
||||
clearTimeout(this._timeoutId);
|
||||
this._showMessageNotification(this._heldMessage, this._msgCounter);
|
||||
this._timeoutId = setTimeout(() => {
|
||||
this._showMessageNotification(this._heldMessage, this._msgCounter);
|
||||
}, kTimeToWaitForMoreMsgs * 1000);
|
||||
}
|
||||
this._lastMessageSender = sender;
|
||||
this._lastMessageTime = aSubject.time;
|
||||
this._showMessageNotification(aSubject);
|
||||
} else if (
|
||||
this._lastMessageSender == sender &&
|
||||
this._lastMessageTime + kTimeToWaitForMoreMsgs >= aSubject.time
|
||||
) {
|
||||
// If the sender is same as the previous sender and the time elapsed since the
|
||||
// last held message is less than kTimeToWaitForMoreMsgs, we increase the held messages
|
||||
// counter and update the last message's arrival time.
|
||||
this._lastMessageTime = aSubject.time;
|
||||
if (!this._heldMessage) {
|
||||
this._heldMessage = aSubject;
|
||||
} else {
|
||||
this._msgCounter++;
|
||||
break;
|
||||
|
||||
case "new-otr-verification-request":
|
||||
// If the Chat tab is not focused, play the sounds and update the icon
|
||||
// counter, and show the counter in the buddy richlistitem.
|
||||
let win = Services.wm.getMostRecentWindow("mail:3pane");
|
||||
if (
|
||||
!Services.focus.activeWindow ||
|
||||
win.document.getElementById("tabmail").currentTabInfo.mode.name !=
|
||||
"chat"
|
||||
) {
|
||||
Services.obs.notifyObservers(
|
||||
aSubject,
|
||||
"play-chat-notification-sound"
|
||||
);
|
||||
}
|
||||
|
||||
clearTimeout(this._timeoutId);
|
||||
this._timeoutId = setTimeout(function() {
|
||||
Notifications._showMessageNotification(
|
||||
Notifications._heldMessage,
|
||||
Notifications._msgCounter
|
||||
);
|
||||
}, kTimeToWaitForMoreMsgs * 1000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче