[gnome-shell] status/network: Factor out ItemSorter class



commit e84ab815d2d623f6a3c4a300d27c50aa59e8cab3
Author: Florian Müllner <fmuellner gnome org>
Date:   Wed Aug 3 16:05:20 2022 +0200

    status/network: Factor out ItemSorter class
    
    At its core, it's the sort order tracking from NMConnectionItem
    with a bit of sugar on top to provide access to the ordered items
    and the ability to provide a custom sort function.
    
    Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2407>

 js/ui/status/network.js | 69 +++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 55 insertions(+), 14 deletions(-)
---
diff --git a/js/ui/status/network.js b/js/ui/status/network.js
index 2a241f7d7a..e7979e03b8 100644
--- a/js/ui/status/network.js
+++ b/js/ui/status/network.js
@@ -98,6 +98,56 @@ function launchSettingsPanel(panel, ...args) {
     }
 }
 
+class ItemSorter {
+    [Symbol.iterator] = this.items;
+
+    /**
+     * Maintains a list of sorted items. By default, items are
+     * assumed to be objects with a name property.
+     *
+     * @param {object=} options - property object with options
+     * @param {Function} options.sortFunc - a custom sort function
+     **/
+    constructor(options = {}) {
+        const {sortFunc} = {
+            sortFunc: this._sortByName.bind(this),
+            ...options,
+        };
+
+        this._sortFunc = sortFunc;
+
+        this._itemsOrder = [];
+    }
+
+    *items() {
+        yield* this._itemsOrder;
+    }
+
+    _sortByName(one, two) {
+        return GLib.utf8_collate(one.name, two.name);
+    }
+
+    /**
+     * Insert or update item.
+     *
+     * @param {any} item - the item to upsert
+     * @returns {number} - the sorted position of item
+     */
+    upsert(item) {
+        this.delete(item);
+        return Util.insertSorted(this._itemsOrder, item, this._sortFunc);
+    }
+
+    /**
+     * @param {any} item - item to remove
+     */
+    delete(item) {
+        const pos = this._itemsOrder.indexOf(item);
+        if (pos >= 0)
+            this._itemsOrder.splice(pos, 1);
+    }
+}
+
 const NMConnectionItem = GObject.registerClass({
     Properties: {
         'radio-mode': GObject.ParamSpec.boolean('radio-mode', '', '',
@@ -265,7 +315,7 @@ var NMConnectionSection = class NMConnectionSection extends Signals.EventEmitter
         this._client = client;
 
         this._connectionItems = new Map();
-        this._itemsOrder = [];
+        this._itemSorter = new ItemSorter();
 
         this._section = new PopupMenu.PopupMenuSection();
 
@@ -306,10 +356,6 @@ var NMConnectionSection = class NMConnectionSection extends Signals.EventEmitter
         return true;
     }
 
-    _itemSortFunction(one, two) {
-        return GLib.utf8_collate(one.name, two.name);
-    }
-
     _makeConnectionItem(connection) {
         return new NMConnectionItem(this, connection);
     }
@@ -337,10 +383,7 @@ var NMConnectionSection = class NMConnectionSection extends Signals.EventEmitter
     _updateForConnection(item, connection) {
         item.updateForConnection(connection);
 
-        let pos = this._itemsOrder.indexOf(item);
-
-        this._itemsOrder.splice(pos, 1);
-        pos = Util.insertSorted(this._itemsOrder, item, this._itemSortFunction.bind(this));
+        const pos = this._itemSorter.upsert(item);
         this._section.moveMenuItem(item, pos);
     }
 
@@ -353,7 +396,7 @@ var NMConnectionSection = class NMConnectionSection extends Signals.EventEmitter
         item.connect('activation-failed', () => this.emit('activation-failed'));
         item.connect('notify::name', this._sync.bind(this));
 
-        let pos = Util.insertSorted(this._itemsOrder, item, this._itemSortFunction.bind(this));
+        const pos = this._itemSorter.upsert(item);
         this._section.addMenuItem(item, pos);
         this._connectionItems.set(connection.get_uuid(), item);
         this._sync();
@@ -365,11 +408,9 @@ var NMConnectionSection = class NMConnectionSection extends Signals.EventEmitter
         if (item == undefined)
             return;
 
-        const pos = this._itemsOrder.indexOf(item);
-        this._itemsOrder.splice(pos, 1);
-
-        item.destroy();
+        this._itemSorter.delete(item);
         this._connectionItems.delete(uuid);
+        item.destroy();
 
         this._sync();
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]