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>
This commit is contained in:
parent
be950d5c4a
commit
e84ab815d2
@ -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({
|
const NMConnectionItem = GObject.registerClass({
|
||||||
Properties: {
|
Properties: {
|
||||||
'radio-mode': GObject.ParamSpec.boolean('radio-mode', '', '',
|
'radio-mode': GObject.ParamSpec.boolean('radio-mode', '', '',
|
||||||
@ -265,7 +315,7 @@ var NMConnectionSection = class NMConnectionSection extends Signals.EventEmitter
|
|||||||
this._client = client;
|
this._client = client;
|
||||||
|
|
||||||
this._connectionItems = new Map();
|
this._connectionItems = new Map();
|
||||||
this._itemsOrder = [];
|
this._itemSorter = new ItemSorter();
|
||||||
|
|
||||||
this._section = new PopupMenu.PopupMenuSection();
|
this._section = new PopupMenu.PopupMenuSection();
|
||||||
|
|
||||||
@ -306,10 +356,6 @@ var NMConnectionSection = class NMConnectionSection extends Signals.EventEmitter
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_itemSortFunction(one, two) {
|
|
||||||
return GLib.utf8_collate(one.name, two.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
_makeConnectionItem(connection) {
|
_makeConnectionItem(connection) {
|
||||||
return new NMConnectionItem(this, connection);
|
return new NMConnectionItem(this, connection);
|
||||||
}
|
}
|
||||||
@ -337,10 +383,7 @@ var NMConnectionSection = class NMConnectionSection extends Signals.EventEmitter
|
|||||||
_updateForConnection(item, connection) {
|
_updateForConnection(item, connection) {
|
||||||
item.updateForConnection(connection);
|
item.updateForConnection(connection);
|
||||||
|
|
||||||
let pos = this._itemsOrder.indexOf(item);
|
const pos = this._itemSorter.upsert(item);
|
||||||
|
|
||||||
this._itemsOrder.splice(pos, 1);
|
|
||||||
pos = Util.insertSorted(this._itemsOrder, item, this._itemSortFunction.bind(this));
|
|
||||||
this._section.moveMenuItem(item, pos);
|
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('activation-failed', () => this.emit('activation-failed'));
|
||||||
item.connect('notify::name', this._sync.bind(this));
|
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._section.addMenuItem(item, pos);
|
||||||
this._connectionItems.set(connection.get_uuid(), item);
|
this._connectionItems.set(connection.get_uuid(), item);
|
||||||
this._sync();
|
this._sync();
|
||||||
@ -365,11 +408,9 @@ var NMConnectionSection = class NMConnectionSection extends Signals.EventEmitter
|
|||||||
if (item == undefined)
|
if (item == undefined)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const pos = this._itemsOrder.indexOf(item);
|
this._itemSorter.delete(item);
|
||||||
this._itemsOrder.splice(pos, 1);
|
|
||||||
|
|
||||||
item.destroy();
|
|
||||||
this._connectionItems.delete(uuid);
|
this._connectionItems.delete(uuid);
|
||||||
|
item.destroy();
|
||||||
|
|
||||||
this._sync();
|
this._sync();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user