Bug 1144823 - reading list sidebar should be sorted by most recently added, r=markh. a=readinglist
authorFlorian Quèze <florian@queze.net>
Fri, 20 Mar 2015 12:07:16 -0700
changeset 248449 2dbde197a04e343d806d345ed81da18c031533e6
parent 248448 4c492ecaf5e7d2b5a4f4aeb73b1119aa612d7d73
child 248450 de26a56440142abcdf236a886a3031ae3c24710f
push id7837
push userjwein@mozilla.com
push dateFri, 27 Mar 2015 00:27:16 +0000
treeherdermozilla-aurora@cb0db44ce60e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmarkh, readinglist
bugs1144823
milestone38.0a2
Bug 1144823 - reading list sidebar should be sorted by most recently added, r=markh. a=readinglist
browser/base/content/browser-readinglist.js
browser/components/readinglist/ReadingList.jsm
browser/components/readinglist/SQLiteStore.jsm
browser/components/readinglist/sidebar.js
--- a/browser/base/content/browser-readinglist.js
+++ b/browser/base/content/browser-readinglist.js
@@ -173,17 +173,17 @@ let ReadingListUI = {
       Favicons.getFaviconURLForPage(item.uri, uri => {
         if (uri) {
           menuitem.setAttribute("image",
                                 Favicons.getFaviconLinkForIcon(uri).spec);
         }
       });
 
       target.insertBefore(menuitem, insertPoint);
-    });
+    }, {sort: "addedOn", descending: true});
 
     if (!hasItems) {
       let menuitem = document.createElement("menuitem");
       let bundle =
         Services.strings.createBundle("chrome://browser/locale/places/places.properties");
       menuitem.setAttribute("label", bundle.GetStringFromName("bookmarksMenuEmptyFolder"));
       menuitem.setAttribute("class", "bookmark-item");
       menuitem.setAttribute("disabled", true);
--- a/browser/components/readinglist/ReadingList.jsm
+++ b/browser/components/readinglist/ReadingList.jsm
@@ -219,16 +219,21 @@ ReadingListImpl.prototype = {
    *
    * @param obj A simple object representing an item.
    * @return Promise<ReadingListItem> Resolved with the new item when the list
    *         is updated.  Rejected with an Error on error.
    */
   addItem: Task.async(function* (obj) {
     obj = stripNonItemProperties(obj);
     normalizeReadingListProperties(obj);
+
+    obj.addedOn = Date.now();
+    if (Services.prefs.prefHasUserValue("services.sync.client.name"))
+      obj.addedBy = Services.prefs.getCharPref("services.sync.client.name");
+
     yield this._store.addItem(obj);
     this._invalidateIterators();
     let item = this._itemFromObject(obj);
     this._callListeners("onItemAdded", item);
     let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
     mm.broadcastAsyncMessage("Reader:Added", item);
     return item;
   }),
--- a/browser/components/readinglist/SQLiteStore.jsm
+++ b/browser/components/readinglist/SQLiteStore.jsm
@@ -66,17 +66,17 @@ this.SQLiteStore.prototype = {
     let conn = yield this._connectionPromise;
     yield conn.executeCached(`
       SELECT ${colNames} FROM items ${sql};
     `, args, row => callback(itemFromRow(row)));
   }),
 
   /**
    * Adds an item to the store that isn't already present.  See
-   * ReadingList.prototype.addItems.
+   * ReadingList.prototype.addItem.
    *
    * @param items A simple object representing an item.
    * @return Promise<null> Resolved when the store is updated.  Rejected with an
    *         Error on error.
    */
   addItem: Task.async(function* (item) {
     let colNames = [];
     let paramNames = [];
--- a/browser/components/readinglist/sidebar.js
+++ b/browser/components/readinglist/sidebar.js
@@ -81,22 +81,27 @@ let RLSidebar = {
 
   /**
    * Handle an item being added to the ReadingList.
    * TODO: We may not want to show this new item right now.
    * TODO: We should guard against the list growing here.
    *
    * @param {ReadinglistItem} item - Item that was added.
    */
-  onItemAdded(item) {
+  onItemAdded(item, append = false) {
     log.trace(`onItemAdded: ${item}`);
 
     let itemNode = document.importNode(this.itemTemplate.content, true).firstElementChild;
     this.updateItem(item, itemNode);
-    this.list.appendChild(itemNode);
+    // XXX Inserting at the top by default is a temp hack that will stop
+    // working once we start including items received from sync.
+    if (append)
+      this.list.appendChild(itemNode);
+    else
+      this.list.insertBefore(itemNode, this.list.firstChild);
     this.itemNodesById.set(item.id, itemNode);
     this.itemsById.set(item.id, item);
 
     this.emptyListInfo.hidden = true;
   },
 
   /**
    * Handle an item being deleted from the ReadingList.
@@ -151,21 +156,21 @@ let RLSidebar = {
 
   /**
    * Ensure that the list is populated with the correct items.
    */
   ensureListItems: Task.async(function* () {
     yield ReadingList.forEachItem(item => {
       // TODO: Should be batch inserting via DocumentFragment
       try {
-        this.onItemAdded(item);
+        this.onItemAdded(item, true);
       } catch (e) {
         log.warn("Error adding item", e);
       }
-    });
+    }, {sort: "addedOn", descending: true});
     this.emptyListInfo.hidden = (this.numItems > 0);
   }),
 
   /**
    * Get the number of items currently displayed in the list.
    * @type {number}
    */
   get numItems() {