status/network: Add ItemSorter option to track MRU
We always display items sorted by name, but there are cases where a second order by recency is interesting. Add an option to ItemSorter to keep such a list and allow accessing it with another generator function. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2407>
This commit is contained in:
parent
a3dbb3e71f
commit
911762ea54
@ -93,28 +93,58 @@ class ItemSorter {
|
|||||||
* Maintains a list of sorted items. By default, items are
|
* Maintains a list of sorted items. By default, items are
|
||||||
* assumed to be objects with a name property.
|
* assumed to be objects with a name property.
|
||||||
*
|
*
|
||||||
|
* Optionally items can have a secondary sort order by
|
||||||
|
* recency. If used, items must by objects with a timestamp
|
||||||
|
* property that can be used in substraction, and "bigger"
|
||||||
|
* must mean "more recent". Number and Date both qualify.
|
||||||
|
*
|
||||||
* @param {object=} options - property object with options
|
* @param {object=} options - property object with options
|
||||||
* @param {Function} options.sortFunc - a custom sort function
|
* @param {Function} options.sortFunc - a custom sort function
|
||||||
|
* @param {bool} options.trackMru - whether to track MRU order as well
|
||||||
**/
|
**/
|
||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
const {sortFunc} = {
|
const {sortFunc, trackMru} = {
|
||||||
sortFunc: this._sortByName.bind(this),
|
sortFunc: this._sortByName.bind(this),
|
||||||
|
trackMru: false,
|
||||||
...options,
|
...options,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this._trackMru = trackMru;
|
||||||
this._sortFunc = sortFunc;
|
this._sortFunc = sortFunc;
|
||||||
|
this._sortFuncMru = this._sortByMru.bind(this);
|
||||||
|
|
||||||
this._itemsOrder = [];
|
this._itemsOrder = [];
|
||||||
|
this._itemsMruOrder = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
*items() {
|
*items() {
|
||||||
yield* this._itemsOrder;
|
yield* this._itemsOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*itemsByMru() {
|
||||||
|
console.assert(this._trackMru, 'itemsByMru: MRU tracking is disabled');
|
||||||
|
yield* this._itemsMruOrder;
|
||||||
|
}
|
||||||
|
|
||||||
_sortByName(one, two) {
|
_sortByName(one, two) {
|
||||||
return GLib.utf8_collate(one.name, two.name);
|
return GLib.utf8_collate(one.name, two.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_sortByMru(one, two) {
|
||||||
|
return two.timestamp - one.timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
_upsert(array, item, sortFunc) {
|
||||||
|
this._delete(array, item);
|
||||||
|
return Util.insertSorted(array, item, sortFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
_delete(array, item) {
|
||||||
|
const pos = array.indexOf(item);
|
||||||
|
if (pos >= 0)
|
||||||
|
array.splice(pos, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert or update item.
|
* Insert or update item.
|
||||||
*
|
*
|
||||||
@ -122,17 +152,19 @@ class ItemSorter {
|
|||||||
* @returns {number} - the sorted position of item
|
* @returns {number} - the sorted position of item
|
||||||
*/
|
*/
|
||||||
upsert(item) {
|
upsert(item) {
|
||||||
this.delete(item);
|
if (this._trackMru)
|
||||||
return Util.insertSorted(this._itemsOrder, item, this._sortFunc);
|
this._upsert(this._itemsMruOrder, item, this._sortFuncMru);
|
||||||
|
|
||||||
|
return this._upsert(this._itemsOrder, item, this._sortFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {any} item - item to remove
|
* @param {any} item - item to remove
|
||||||
*/
|
*/
|
||||||
delete(item) {
|
delete(item) {
|
||||||
const pos = this._itemsOrder.indexOf(item);
|
if (this._trackMru)
|
||||||
if (pos >= 0)
|
this._delete(this._itemsMruOrder, item);
|
||||||
this._itemsOrder.splice(pos, 1);
|
this._delete(this._itemsOrder, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user