Files
binoc-central-mirror/mail/components/compose/content/bigFileObserver.js
T
2020-05-10 13:52:36 -04:00

307 lines
10 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource:///modules/cloudFileAccounts.js");
var kUploadNotificationValue = "bigAttachmentUploading";
var kPrivacyWarningNotificationValue = "bigAttachmentPrivacyWarning";
var gBigFileObserver = {
bigFiles: [],
sessionHidden: false,
privacyWarned: false,
get hidden() {
return this.sessionHidden ||
!Services.prefs.getBoolPref("mail.cloud_files.enabled") ||
!Services.prefs.getBoolPref("mail.compose.big_attachments.notify") ||
Services.io.offline;
},
hide: function(aPermanent) {
if (aPermanent)
Services.prefs.setBoolPref("mail.compose.big_attachments.notify", false);
else
this.sessionHidden = true;
},
init: function() {
let bucket = document.getElementById("attachmentBucket");
bucket.addEventListener("attachments-added", this, false);
bucket.addEventListener("attachments-removed", this, false);
bucket.addEventListener("attachments-uploading", this, false);
bucket.addEventListener("attachment-uploaded", this, false);
bucket.addEventListener("attachment-upload-failed", this, false);
bucket.addEventListener("attachments-converted", this, false);
this.sessionHidden = false;
this.privacyWarned = false;
this.bigFiles = [];
},
handleEvent: function(event) {
if (this.hidden)
return;
const bucketCallbacks = {
"attachments-added": this.attachmentsAdded,
"attachments-removed": this.attachmentsRemoved,
"attachments-converted": this.attachmentsConverted,
"attachments-uploading": this.attachmentsUploading,
};
const itemCallbacks = {
"attachment-uploaded": this.attachmentUploaded,
"attachment-upload-failed": this.attachmentUploadFailed,
}
if (event.type in bucketCallbacks)
bucketCallbacks[event.type].call(this, event.detail);
if (event.type in itemCallbacks)
itemCallbacks[event.type].call(this, event.target,
("detail" in event) ? event.detail : null);
this.updateNotification();
},
formatString: function (key, replacements, plural) {
let str = getComposeBundle().getString(key);
if (plural !== undefined)
str = PluralForm.get(plural, str);
if (replacements !== undefined) {
for (let i = 0; i < replacements.length; i++)
str = str.replace("#" + (i + 1), replacements[i]);
}
return str;
},
attachmentsAdded: function(aAttachments) {
let threshold = Services.prefs.getIntPref(
"mail.compose.big_attachments.threshold_kb") * 1024;
for (let attachment in fixIterator(
aAttachments, Components.interfaces.nsIMsgAttachment)) {
if (attachment.size >= threshold && !attachment.sendViaCloud)
this.bigFiles.push(attachment);
}
},
attachmentsRemoved: function(aAttachments) {
for (let attachment in fixIterator(
aAttachments, Components.interfaces.nsIMsgAttachment)) {
let index = this.bigFiles.indexOf(attachment);
if (index != -1)
this.bigFiles.splice(index, 1);
}
},
attachmentsConverted: function(aAttachments) {
let uploaded = [];
for (let attachment in fixIterator(
aAttachments, Components.interfaces.nsIMsgAttachment)) {
if (attachment.sendViaCloud) {
this.attachmentsRemoved([attachment]);
uploaded.push(attachment);
}
}
if (uploaded.length)
this.showUploadingNotification(uploaded);
},
attachmentsUploading: function(aAttachments) {
this.showUploadingNotification(aAttachments);
},
attachmentUploaded: function(aAttachment) {
if (!this._anyUploadsInProgress()) {
this.hideUploadingNotification();
if (!this.privacyWarned) {
this.showPrivacyNotification();
this.privacyWarned = true;
}
}
},
attachmentUploadFailed: function(aAttachment, aStatusCode) {
if (!this._anyUploadsInProgress())
this.hideUploadingNotification();
},
updateNotification: function() {
let nb = document.getElementById("attachmentNotificationBox");
let notification = nb.getNotificationWithValue("bigAttachment");
let numAccounts = cloudFileAccounts.accounts.length;
if (this.bigFiles.length) {
if (notification) {
notification.label = this.formatString("bigFileDescription",
[this.bigFiles.length],
this.bigFiles.length);
return;
}
let buttons = [
{
label: getComposeBundle().getString("learnMore.label"),
accessKey: getComposeBundle().getString("learnMore.accesskey"),
callback: this.openLearnMore.bind(this),
},
{ label: this.formatString("bigFileShare.label",
[]),
accessKey: this.formatString("bigFileShare.accesskey"),
callback: this.convertAttachments.bind(this),
},
{ label: this.formatString("bigFileAttach.label",
[]),
accessKey: this.formatString("bigFileAttach.accesskey"),
callback: this.hideNotification.bind(this),
},
];
let msg = this.formatString("bigFileDescription", [this.bigFiles.length],
this.bigFiles.length);
notification = nb.appendNotification(msg, "bigAttachment", "null",
nb.PRIORITY_WARNING_MEDIUM,
buttons);
}
else {
if (notification)
nb.removeNotification(notification);
}
},
openLearnMore: function() {
let url = Services.prefs.getCharPref("mail.cloud_files.learn_more_url");
openContentTab(url);
return true;
},
convertAttachments: function() {
let cloudProvider;
let accounts = cloudFileAccounts.accounts;
if (accounts.length == 1) {
cloudProvider = accounts[0];
}
else if(accounts.length > 1) {
let selection = {};
let names = accounts.map(i => cloudFileAccounts.getDisplayName(i));
if (Services.prompt.select(window,
this.formatString("bigFileChooseAccount.title"),
this.formatString("bigFileChooseAccount.text"),
names.length, names, selection))
cloudProvider = accounts[selection.value];
}
else {
let accountKey = cloudFileAccounts.addAccountDialog();
if (accountKey)
cloudProvider = cloudFileAccounts.getAccount(accountKey);
else
return true;
}
if (cloudProvider)
convertToCloudAttachment(this.bigFiles, cloudProvider);
},
hideNotification: function() {
let never = {};
if (Services.prompt.confirmCheck(window,
this.formatString("bigFileHideNotification.title"),
this.formatString("bigFileHideNotification.text"),
this.formatString("bigFileHideNotification.check"),
never))
this.hide(never.value);
else
return true;
},
showUploadingNotification: function(aAttachments) {
// We will show the uploading notification for a minimum of 2.5 seconds
// seconds.
const kThreshold = 2500; // milliseconds
if (!aAttachments.length ||
!Services.prefs
.getBoolPref("mail.compose.big_attachments.insert_notification"))
return;
let nb = document.getElementById("attachmentNotificationBox");
let notification = nb.getNotificationWithValue(kUploadNotificationValue);
if (notification)
return;
let message = this.formatString("cloudFileUploadingNotification");
message = PluralForm.get(aAttachments.length, message);
let showUploadButton = {
accessKey: this.formatString("stopShowingUploadingNotification.accesskey"),
label: this.formatString("stopShowingUploadingNotification.label"),
callback: function (aNotificationBar, aButton)
{
Services.prefs.setBoolPref("mail.compose.big_attachments.insert_notification", false);
}
};
notification = nb.appendNotification(message, kUploadNotificationValue,
"null", nb.PRIORITY_WARNING_MEDIUM,
[showUploadButton]);
notification.timeout = Date.now() + kThreshold;
},
hideUploadingNotification: function() {
let nb = document.getElementById("attachmentNotificationBox");
let notification = nb.getNotificationWithValue(kUploadNotificationValue);
if (notification) {
// Check the timestamp that we stashed in the timeout field of the
// notification...
let now = Date.now();
if (now >= notification.timeout) {
nb.removeNotification(notification);
} else {
setTimeout(function() {
nb.removeNotification(notification);
}, notification.timeout - now);
}
}
},
showPrivacyNotification: function() {
const kPrivacyNotificationValue = "bigAttachmentPrivacyWarning";
let nb = document.getElementById("attachmentNotificationBox");
let notification = nb.getNotificationWithValue(kPrivacyNotificationValue);
if (notification)
return;
let message = this.formatString("cloudFilePrivacyNotification");
nb.appendNotification(message, kPrivacyNotificationValue, "null",
nb.PRIORITY_WARNING_MEDIUM, null);
},
_anyUploadsInProgress: function() {
let bucket = document.getElementById("attachmentBucket");
let rowCount = bucket.getRowCount();
for (let i = 0; i < bucket.getRowCount(); ++i) {
let item = bucket.getItemAtIndex(i);
if (item && item.uploading)
return true;
}
return false;
},
};
window.addEventListener("compose-window-init",
gBigFileObserver.init.bind(gBigFileObserver), true);