summaryrefslogtreecommitdiffstats
path: root/comm/mail/components/activity/modules/sendLater.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/components/activity/modules/sendLater.jsm')
-rw-r--r--comm/mail/components/activity/modules/sendLater.jsm298
1 files changed, 298 insertions, 0 deletions
diff --git a/comm/mail/components/activity/modules/sendLater.jsm b/comm/mail/components/activity/modules/sendLater.jsm
new file mode 100644
index 0000000000..37027d96f1
--- /dev/null
+++ b/comm/mail/components/activity/modules/sendLater.jsm
@@ -0,0 +1,298 @@
+/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+const EXPORTED_SYMBOLS = ["sendLaterModule"];
+
+var nsActProcess = Components.Constructor(
+ "@mozilla.org/activity-process;1",
+ "nsIActivityProcess",
+ "init"
+);
+var nsActEvent = Components.Constructor(
+ "@mozilla.org/activity-event;1",
+ "nsIActivityEvent",
+ "init"
+);
+var nsActWarning = Components.Constructor(
+ "@mozilla.org/activity-warning;1",
+ "nsIActivityWarning",
+ "init"
+);
+
+/**
+ * This really, really, sucks. Due to mailnews widespread use of
+ * nsIMsgStatusFeedback we're bound to the UI to get any sensible feedback of
+ * mail sending operations. The current send later code can't hook into the
+ * progress listener easily to get the state of messages being sent, so we'll
+ * just have to do it here.
+ */
+var sendMsgProgressListener = {
+ QueryInterface: ChromeUtils.generateQI([
+ "nsIMsgStatusFeedback",
+ "nsISupportsWeakReference",
+ ]),
+
+ showStatusString(aStatusText) {
+ sendLaterModule.onMsgStatus(aStatusText);
+ },
+
+ startMeteors() {},
+
+ stopMeteors() {},
+
+ showProgress(aPercentage) {
+ sendLaterModule.onMessageSendProgress(0, 0, aPercentage, 0);
+ },
+};
+
+// This module provides a link between the send later service and the activity
+// manager.
+var sendLaterModule = {
+ _sendProcess: null,
+ _copyProcess: null,
+ _identity: null,
+ _subject: null,
+
+ get log() {
+ delete this.log;
+ return (this.log = console.createInstance({
+ prefix: "mail.activity",
+ maxLogLevel: "Warn",
+ maxLogLevelPref: "mail.activity.loglevel",
+ }));
+ },
+
+ get activityMgr() {
+ delete this.activityMgr;
+ return (this.activityMgr = Cc["@mozilla.org/activity-manager;1"].getService(
+ Ci.nsIActivityManager
+ ));
+ },
+
+ get bundle() {
+ delete this.bundle;
+ return (this.bundle = Services.strings.createBundle(
+ "chrome://messenger/locale/activity.properties"
+ ));
+ },
+
+ QueryInterface: ChromeUtils.generateQI(["nsIMsgSendLaterListener"]),
+
+ _displayTextForHeader(aLocaleStringBase, aSubject) {
+ return aSubject
+ ? this.bundle.formatStringFromName(aLocaleStringBase + "WithSubject", [
+ aSubject,
+ ])
+ : this.bundle.GetStringFromName(aLocaleStringBase);
+ },
+
+ _newProcess(aLocaleStringBase, aAddSubject) {
+ let process = new nsActProcess(
+ this._displayTextForHeader(
+ aLocaleStringBase,
+ aAddSubject ? this._subject : ""
+ ),
+ this.activityMgr
+ );
+
+ process.iconClass = "sendMail";
+ process.groupingStyle = Ci.nsIActivity.GROUPING_STYLE_BYCONTEXT;
+ process.contextObj = this;
+ process.contextType = "SendLater";
+ process.contextDisplayText =
+ this.bundle.GetStringFromName("sendingMessages");
+
+ return process;
+ },
+
+ // Use this to group an activity by the identity if we have one.
+ _applyIdentityGrouping(aActivity) {
+ if (this._identity) {
+ aActivity.groupingStyle = Ci.nsIActivity.GROUPING_STYLE_BYCONTEXT;
+ aActivity.contextType = this._identity.key;
+ aActivity.contextObj = this._identity;
+ let contextDisplayText = this._identity.identityName;
+ if (!contextDisplayText) {
+ contextDisplayText = this._identity.email;
+ }
+
+ aActivity.contextDisplayText = contextDisplayText;
+ } else {
+ aActivity.groupingStyle = Ci.nsIActivity.GROUPING_STYLE_STANDALONE;
+ }
+ },
+
+ // Replaces the process with an event that reflects a completed process.
+ _replaceProcessWithEvent(aProcess) {
+ this.activityMgr.removeActivity(aProcess.id);
+
+ let event = new nsActEvent(
+ this._displayTextForHeader("sentMessage", this._subject),
+ this.activityMgr,
+ "",
+ aProcess.startTime,
+ new Date()
+ );
+
+ event.iconClass = "sendMail";
+ this._applyIdentityGrouping(event);
+
+ this.activityMgr.addActivity(event);
+ },
+
+ // Replaces the process with a warning that reflects the failed process.
+ _replaceProcessWithWarning(
+ aProcess,
+ aCopyOrSend,
+ aStatus,
+ aMsg,
+ aMessageHeader
+ ) {
+ this.activityMgr.removeActivity(aProcess.id);
+
+ let warning = new nsActWarning(
+ this._displayTextForHeader("failedTo" + aCopyOrSend, this._subject),
+ this.activityMgr,
+ ""
+ );
+
+ warning.groupingStyle = Ci.nsIActivity.GROUPING_STYLE_STANDALONE;
+ this._applyIdentityGrouping(warning);
+
+ this.activityMgr.addActivity(warning);
+ },
+
+ onStartSending(aTotalMessageCount) {
+ if (!aTotalMessageCount) {
+ this.log.error("onStartSending called with zero messages\n");
+ }
+ },
+
+ onMessageStartSending(
+ aCurrentMessage,
+ aTotalMessageCount,
+ aMessageHeader,
+ aIdentity
+ ) {
+ // We want to use the identity and subject later, so store them for now.
+ this._identity = aIdentity;
+ if (aMessageHeader) {
+ this._subject = aMessageHeader.mime2DecodedSubject;
+ }
+
+ // Create the process to display the send activity.
+ let process = this._newProcess("sendingMessage", true);
+ this._sendProcess = process;
+ this.activityMgr.addActivity(process);
+
+ // Now the one for the copy process.
+ process = this._newProcess("copyMessage", false);
+ this._copyProcess = process;
+ this.activityMgr.addActivity(process);
+ },
+
+ onMessageSendProgress(
+ aCurrentMessage,
+ aTotalMessageCount,
+ aMessageSendPercent,
+ aMessageCopyPercent
+ ) {
+ if (aMessageSendPercent < 100) {
+ // Ensure we are in progress...
+ if (this._sendProcess.state != Ci.nsIActivityProcess.STATE_INPROGRESS) {
+ this._sendProcess.state = Ci.nsIActivityProcess.STATE_INPROGRESS;
+ }
+
+ // ... and update the progress.
+ this._sendProcess.setProgress(
+ this._sendProcess.lastStatusText,
+ aMessageSendPercent,
+ 100
+ );
+ } else if (aMessageSendPercent == 100) {
+ if (aMessageCopyPercent == 0) {
+ // Set send state to completed
+ if (this._sendProcess.state != Ci.nsIActivityProcess.STATE_COMPLETED) {
+ this._sendProcess.state = Ci.nsIActivityProcess.STATE_COMPLETED;
+ }
+ this._replaceProcessWithEvent(this._sendProcess);
+
+ // Set copy state to in progress.
+ if (this._copyProcess.state != Ci.nsIActivityProcess.STATE_INPROGRESS) {
+ this._copyProcess.state = Ci.nsIActivityProcess.STATE_INPROGRESS;
+ }
+
+ // We don't know the progress of the copy, so just set to 0, and we'll
+ // display an undetermined progress meter.
+ this._copyProcess.setProgress(this._copyProcess.lastStatusText, 0, 0);
+ } else if (aMessageCopyPercent >= 100) {
+ // We need to set this to completed otherwise activity manager
+ // complains.
+ if (this._copyProcess) {
+ this._copyProcess.state = Ci.nsIActivityProcess.STATE_COMPLETED;
+ this.activityMgr.removeActivity(this._copyProcess.id);
+ this._copyProcess = null;
+ }
+
+ this._sendProcess = null;
+ }
+ }
+ },
+
+ onMessageSendError(aCurrentMessage, aMessageHeader, aStatus, aMsg) {
+ if (
+ this._sendProcess &&
+ this._sendProcess.state != Ci.nsIActivityProcess.STATE_COMPLETED
+ ) {
+ this._sendProcess.state = Ci.nsIActivityProcess.STATE_COMPLETED;
+ this._replaceProcessWithWarning(
+ this._sendProcess,
+ "SendMessage",
+ aStatus,
+ aMsg,
+ aMessageHeader
+ );
+ this._sendProcess = null;
+
+ if (
+ this._copyProcess &&
+ this._copyProcess.state != Ci.nsIActivityProcess.STATE_COMPLETED
+ ) {
+ this._copyProcess.state = Ci.nsIActivityProcess.STATE_COMPLETED;
+ this.activityMgr.removeActivity(this._copyProcess.id);
+ this._copyProcess = null;
+ }
+ }
+ },
+
+ onMsgStatus(aStatusText) {
+ this._sendProcess.setProgress(
+ aStatusText,
+ this._sendProcess.workUnitComplete,
+ this._sendProcess.totalWorkUnits
+ );
+ },
+
+ onStopSending(aStatus, aMsg, aTotalTried, aSuccessful) {},
+
+ init() {
+ // We should need to remove the listener as we're not being held by anyone
+ // except by the send later instance.
+ let sendLaterService = Cc[
+ "@mozilla.org/messengercompose/sendlater;1"
+ ].getService(Ci.nsIMsgSendLater);
+
+ sendLaterService.addListener(this);
+
+ // Also add the nsIMsgStatusFeedback object.
+ let statusFeedback = Cc[
+ "@mozilla.org/messenger/statusfeedback;1"
+ ].createInstance(Ci.nsIMsgStatusFeedback);
+
+ statusFeedback.setWrappedStatusFeedback(sendMsgProgressListener);
+
+ sendLaterService.statusFeedback = statusFeedback;
+ },
+};