MozillaZine

Asynchronous command

Talk about add-ons and extension development.
rashmani
 
Posts: 10
Joined: August 21st, 2014, 2:15 am

Post Posted October 20th, 2016, 10:17 am

Hi there,

I'm trying to write a little of code for a custom button (using Custom Buttons ext.) that performs the following steps:
- enable quick filter for unread messages
- select all of them
- apply filters to selected messages
- disable quick filtering of unread messages
My script should wait for each step to be executed before executing next one.
To accomplish this, I've tried to use Promise, as explained here https://developer.mozilla.org/en-US/doc ... m/Examples

But this doesn't work, I think because I can't just turn something asynchronous into a promise... or maybe I do it wrong.
This is what I have:

Code: Select all
var promiseFilter = promiseApplyFiltersToSelection();

promiseFilter.then(
   function(success) {
        gFolderDisplay.clearSelection();
      alert(uneval(success));
   },
   function(failure) {
      alert("Something went wrong while applying filters: " + uneval(failure));
   }
);

function promiseApplyFiltersToSelection() {
  try {
   document.getElementById("qfb-unread").click(); // select all unread
   goDoCommand("cmd_applyFiltersToSelection"); // apply filters
   
    return Promise.resolve('Filters applied'); // this makes the success function trigger
  } catch(ex) {
    return Promise.reject(ex);
  }
}


This pops up the alert right away, then enable the unread filter but does not select anything...

Anyone can explain and/or point me in the right direction?

TIA,
rash*

rashmani
 
Posts: 10
Joined: August 21st, 2014, 2:15 am

Post Posted October 21st, 2016, 4:00 am

Well,

some progress but still far from target. Of course I have a couple of error/missings in my code, that I've modified to this:

Code: Select all
var promiseFilter = promiseApplyFiltersToSelection();

promiseFilter.then(
   function(success) {
        gFolderDisplay.clearSelection();
      document.getElementById("qfb-unread").click(); // reset unread filter
      alert(uneval(success));
   },
   function(failure) {
      alert("Something went wrong while applying filters: " + uneval(failure));
   }
);

function promiseApplyFiltersToSelection() {
  try {
   document.getElementById("qfb-unread").click(); // filter unread
   goDoCommand("cmd_selectAll"); // select all
   goDoCommand("cmd_applyFiltersToSelection"); // apply filters
   
    return Promise.resolve('Filters applied'); // this makes the success function trigger
  } catch(ex) {
    return Promise.reject(ex);
  }
}


Nevertheless, this code doesn't work, almost: when I click my button, TB hangs processing all messages in current folder, not just unread ones. So for some reason filtering unread, then selecting all, then applying filters to selection do not happen in wanted time sequence (meanwhile I see no activity by TB, filters are applied though).
Should I wrap each step in a promise-returning function and chain those functions with .then()?
Or am I missing some deeper understanding here?

TIA,
rash*

morat
 
Posts: 2901
Joined: February 3rd, 2009, 6:29 pm

Post Posted October 23rd, 2016, 3:27 am

Try using the nsIMsgOperationListener callback.

Code: Select all
void applyFilters(in nsMsgFilterTypeType aFilterType,
                  in nsIArray aMsgHdrList,
                  in nsIMsgFolder aFolder,
                  in nsIMsgWindow aMsgWindow,
                  [optional] in nsIMsgOperationListener aCallback);

Code: Select all
var operationListener = {
  onStopOperation: function (aResult) {
    if (Components.isSuccessCode(aResult)) {
      Application.console.log("Apply filters succeeded.");
    } else {
      Application.console.log("Apply filters failed: " + aResult);
    }
  },
};
var folder = gFolderDisplay.displayedFolder;
var enumerator = folder.messages;
var mutableArray = Components.classes["@mozilla.org/array;1"].
  createInstance(Components.interfaces.nsIMutableArray);
while (enumerator.hasMoreElements()) {
  var msgHdr = enumerator.getNext().
    QueryInterface(Components.interfaces.nsIMsgDBHdr);
  if (!(msgHdr.flags & Components.interfaces.nsMsgMessageFlags.Read)) {
    mutableArray.appendElement(msgHdr, false /*weak*/);
  }
}
if (mutableArray.length) {
  var filterType = Components.interfaces.nsMsgFilterType.Manual;
  MailServices.filters.applyFilters(filterType, mutableArray,
    folder, msgWindow, operationListener);
} else {
  Application.console.log("No unread messages.");
}

http://dxr.mozilla.org/comm-release/sou ... ervice.idl
http://dxr.mozilla.org/comm-release/sou ... stener.idl

rashmani
 
Posts: 10
Joined: August 21st, 2014, 2:15 am

Post Posted October 26th, 2016, 7:01 am

Woh! It works a treat, and it was galaxies beyond my TB's API knowledge.
Huge thanks, also for teaching me something new.

Kudos,
rash*

morat
 
Posts: 2901
Joined: February 3rd, 2009, 6:29 pm

Post Posted October 26th, 2016, 12:14 pm

You're welcome.

Return to Extension Development


Who is online

Users browsing this forum: No registered users and 2 guests