Bug 1551590 - OTR: improve notifications when a chat starts with a verification request. r=kaie

This commit is contained in:
Alessandro Castellani 2020-03-10 22:53:51 +02:00
Родитель 87e443fdb0
Коммит d45e4b377e
11 изменённых файлов: 204 добавлений и 80 удалений

Просмотреть файл

@ -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;
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,16 +189,19 @@ 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 (!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;
@ -238,13 +241,28 @@ var Notifications = {
}
clearTimeout(this._timeoutId);
this._timeoutId = setTimeout(function() {
Notifications._showMessageNotification(
Notifications._heldMessage,
Notifications._msgCounter
);
this._timeoutId = setTimeout(() => {
this._showMessageNotification(this._heldMessage, this._msgCounter);
}, kTimeToWaitForMoreMsgs * 1000);
}
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"
);
}
break;
}
},
};