✨ Sync 2026-08-20 17:28:50

This commit is contained in:
github-actions[bot] committed 2026-08-20 17:28:51 +08:00
1 parent b9459cd94c
commit 9b0206e8fe
22 files changed
+268 -226

No files matched your search

@@ -240,7 +240,23 @@ return view.extend({
return [ fam, pr ].filter(x => x).join(' · ') || '–';
};
const rows = entries.slice().reverse();
/* Sort the whole range here, not just the page: ui.Table only ever
* orders the rows it was handed, so paging first would turn the
* headers into a per-page sort while the count below still speaks
* for every measurement. */
let rows = entries.slice().reverse();
const sorting = this.table.getActiveSortState();
if (sorting)
rows = rows
.map(L.bind(function(r) {
return [ this.table.deriveSortKey(r[sorting[0]], sorting[0]), r ];
}, this))
.sort((a, b) => sorting[1]
? -L.naturalCompare(a[0], b[0])
: L.naturalCompare(a[0], b[0]))
.map(x => x[1]);
const pages = Math.max(1, Math.ceil(rows.length / pageSize));
if (this.page >= pages)
@@ -312,6 +328,14 @@ return view.extend({
_('Download [Mbps]'), _('Upload [Mbps]'), _('Ping [ms]'), _('Jitter [ms]')
], { id: 'librespeed-history' });
this.tableNode = this.table.render();
/* The table's own handler re-sorts the page it holds; this runs
* after it and re-sorts the range, from the first page. */
this.tableNode.addEventListener('click', L.bind(function(ev) {
if (ev.target.closest('th[data-sortable-row], .th[data-sortable-row]')) {
this.page = 0;
this.redraw();
}
}, this));
const renderControls = L.bind(function() {
const groups = lscommon.switcher(this,
@@ -566,16 +566,9 @@ return view.extend({
this.recentMetric = 'download_mbps';
/* Two directions, one chart at a time: the page answers "how am I
* doing" at a glance, and mixing both series would make that a
* comparison instead. History is where series get combined. */
this.recentSwitch = lscommon.switcher(this,
lscommon.GROUPS.speed.map(k => {
const m = lscommon.METRICS.find(x => x[0] == k);
return [ k, m[1] ];
}), this.recentMetric,
function(v) {
this.recentMetric = v;
this.renderRecent(this.recentData);
});
* comparison instead. History is where series get combined. The
* buttons themselves are filled by renderRecent, first call included. */
this.recentSwitch = E('div', {});
this.button = E('button', { 'class': 'cbi-button cbi-button-action' },
[ _('Start test') ]);
@@ -617,7 +610,13 @@ return view.extend({
rows.map(r => E('tr', { 'class': 'tr' }, [
E('td', { 'class': 'td librespeed-muted', 'style': 'width:45%' }, [ r[0] ]),
E('td', { 'class': 'td' }, [
r[2] ? E('span', { 'class': 'librespeed-hint', 'data-tooltip': r[2] }, [ r[1] ]) : r[1]
r[2] ? E('span', {
/* tabindex, or the focus half of "hover or focus"
* never fires: a bare span is not in the tab order. */
'class': 'librespeed-hint',
'tabindex': '0',
'data-tooltip': r[2]
}, [ r[1] ]) : r[1]
])
])));