mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-07 16:09:43 +02:00
fix(web): adopt #263's fetch ceiling, persisted sort and numeric collation
@jordan8037310 opened #263 against the same two issues while this branch was in flight. Three details there are better than what this had, so they are folded in with credit: - the Resume list pulls 200 unified sessions instead of 60, so the filter can reach a real backlog rather than stopping at an arbitrary ceiling (the endpoint clamps at 500), - the sort choice persists per device in localStorage, like `codeman:skin` and the other display keys that stay out of the synced schema, - alphabetical sorts collate with `{sensitivity:'base', numeric:true}`, so w2- sorts before w10- and case never splits one project's rows apart. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1956,8 +1956,16 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
/** Number of history items shown before "Show More" */
|
/** Number of history items shown before "Show More" */
|
||||||
_HISTORY_INITIAL_COUNT: 10,
|
_HISTORY_INITIAL_COUNT: 10,
|
||||||
|
|
||||||
/** How many past sessions the home screen loads (also the filter/sort corpus). */
|
/**
|
||||||
_HISTORY_FETCH_LIMIT: 60,
|
* How many past sessions the home screen loads (also the filter/sort corpus).
|
||||||
|
* 200, not the old 60, so the filter can reach a real backlog — an install with
|
||||||
|
* 35+ conversations would otherwise hit the ceiling before the filter is useful
|
||||||
|
* (raised in @jordan8037310's #263; the endpoint clamps at 500).
|
||||||
|
*/
|
||||||
|
_HISTORY_FETCH_LIMIT: 200,
|
||||||
|
|
||||||
|
/** localStorage key for the per-device sort choice (#263). */
|
||||||
|
_HISTORY_SORT_KEY: 'codeman:historySort',
|
||||||
|
|
||||||
async loadHistorySessions() {
|
async loadHistorySessions() {
|
||||||
const container = document.getElementById('historySessions');
|
const container = document.getElementById('historySessions');
|
||||||
@@ -1995,7 +2003,12 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Wire the filter box and sort select once; both re-render from the cached corpus. */
|
/**
|
||||||
|
* Wire the filter box and sort select once; both re-render from the cached
|
||||||
|
* corpus. The sort choice is restored from (and saved to) localStorage — it is
|
||||||
|
* a per-device display preference, so it stays out of the synced settings
|
||||||
|
* schema, same as `codeman:skin`.
|
||||||
|
*/
|
||||||
_wireHistoryControls() {
|
_wireHistoryControls() {
|
||||||
if (this._historyControlsWired) return;
|
if (this._historyControlsWired) return;
|
||||||
const filter = document.getElementById('historyFilter');
|
const filter = document.getElementById('historyFilter');
|
||||||
@@ -2003,6 +2016,15 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
if (!filter && !sort) return;
|
if (!filter && !sort) return;
|
||||||
this._historyControlsWired = true;
|
this._historyControlsWired = true;
|
||||||
|
|
||||||
|
if (sort) {
|
||||||
|
try {
|
||||||
|
const saved = localStorage.getItem(this._HISTORY_SORT_KEY);
|
||||||
|
if (saved && Array.from(sort.options).some((o) => o.value === saved)) sort.value = saved;
|
||||||
|
} catch {
|
||||||
|
/* private mode — the order just won't persist */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
filter.addEventListener('input', () => this._renderHistoryList());
|
filter.addEventListener('input', () => this._renderHistoryList());
|
||||||
filter.addEventListener('keydown', (ev) => {
|
filter.addEventListener('keydown', (ev) => {
|
||||||
@@ -2014,7 +2036,16 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (sort) sort.addEventListener('change', () => this._renderHistoryList());
|
if (sort) {
|
||||||
|
sort.addEventListener('change', () => {
|
||||||
|
try {
|
||||||
|
localStorage.setItem(this._HISTORY_SORT_KEY, sort.value);
|
||||||
|
} catch {
|
||||||
|
/* private mode — the order just won't persist */
|
||||||
|
}
|
||||||
|
this._renderHistoryList();
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** True when a past-session row matches the filter text (name, folder, case, prompt). */
|
/** True when a past-session row matches the filter text (name, folder, case, prompt). */
|
||||||
@@ -2050,7 +2081,14 @@ Object.assign(CodemanApp.prototype, {
|
|||||||
const label = (s) => this._historyRowLabel(s, this._shortenHomePath(s.workingDir)).toLowerCase();
|
const label = (s) => this._historyRowLabel(s, this._shortenHomePath(s.workingDir)).toLowerCase();
|
||||||
const folder = (s) => ((s.workingDir || '').split('/').pop() || '').toLowerCase();
|
const folder = (s) => ((s.workingDir || '').split('/').pop() || '').toLowerCase();
|
||||||
const key = mode === 'name' ? label : folder;
|
const key = mode === 'name' ? label : folder;
|
||||||
const sorted = mode === 'recent' ? rows.slice() : rows.slice().sort((a, b) => key(a).localeCompare(key(b)));
|
// numeric collation so w2-… sorts before w10-…, and base sensitivity so case
|
||||||
|
// does not split a project's rows apart (from @jordan8037310's #263).
|
||||||
|
const sorted =
|
||||||
|
mode === 'recent'
|
||||||
|
? rows.slice()
|
||||||
|
: rows
|
||||||
|
.slice()
|
||||||
|
.sort((a, b) => key(a).localeCompare(key(b), undefined, { sensitivity: 'base', numeric: true }));
|
||||||
const pinned = sorted.filter((s) => s.pinned);
|
const pinned = sorted.filter((s) => s.pinned);
|
||||||
return pinned.length === 0 ? sorted : pinned.concat(sorted.filter((s) => !s.pinned));
|
return pinned.length === 0 ? sorted : pinned.concat(sorted.filter((s) => !s.pinned));
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user