MovesList: order the TM/HM group by TM number
The learnset's "By TM / HM" group was alphabetical. TM numbers aren't in
the snapshot — they resolve lazily per move via /machine/{id}, which the
group's enrichers already fetch on expand. So: await those resolutions
(fillTm is now async and stashes the label on the move), and once the
whole group is enriched, re-append the rows in TM/HM/TR-then-number order
— TM01, TM02 … HM01 …, matching the in-game list. Verified against
Charizard in FireRed/LeafGreen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ve7HLspzeG2xDPtJQ8vmu
This commit is contained in:
parent
4b9bc5c0ab
commit
d73438dd29
@ -91,7 +91,8 @@ Working app with a type-themed UI:
|
|||||||
Moves / Locations); coloured animated stat bars; defensive type matchups;
|
Moves / Locations); coloured animated stat bars; defensive type matchups;
|
||||||
evolution chain re-parented to the selected game's generation; learnset with
|
evolution chain re-parented to the selected game's generation; learnset with
|
||||||
per-move power/type/accuracy/PP/effect (era-accurate via `past_values`,
|
per-move power/type/accuracy/PP/effect (era-accurate via `past_values`,
|
||||||
incl. pre-Gen-4 physical/special-by-type); wild encounter locations.
|
incl. pre-Gen-4 physical/special-by-type), the TM/HM group ordered by
|
||||||
|
TM number for the selected game; wild encounter locations.
|
||||||
- **Game-aware** — abilities gated to Gen 3+ (hidden to Gen 5+); type chart
|
- **Game-aware** — abilities gated to Gen 3+ (hidden to Gen 5+); type chart
|
||||||
applies Gen 1 / pre-Gen 6 rules.
|
applies Gen 1 / pre-Gen 6 rules.
|
||||||
- **Games** — overlay picker with stylised version-colour cover tiles,
|
- **Games** — overlay picker with stylised version-colour cover tiles,
|
||||||
|
|||||||
@ -27,6 +27,15 @@ const METHOD_LABEL = {
|
|||||||
'form-change': 'On form change',
|
'form-change': 'On form change',
|
||||||
};
|
};
|
||||||
const METHOD_ORDER = ['level-up', 'egg', 'machine', 'tutor', 'form-change'];
|
const METHOD_ORDER = ['level-up', 'egg', 'machine', 'tutor', 'form-change'];
|
||||||
|
|
||||||
|
/** Numeric sort key from a TM/HM/TR label like "TM25": TMs, then HMs, then TRs. */
|
||||||
|
function tmSortKey(label) {
|
||||||
|
if (!label) return 1e9; // not resolved yet -> sink to the bottom
|
||||||
|
const m = String(label).match(/^([A-Z]+)0*(\d+)$/);
|
||||||
|
if (!m) return 1e9 - 1;
|
||||||
|
const rank = { TM: 0, HM: 1, TR: 2 }[m[1]] ?? 3;
|
||||||
|
return rank * 1000 + Number(m[2]);
|
||||||
|
}
|
||||||
const DAMAGE_CLASS = { physical: 'Phys', special: 'Spec', status: 'Stat' };
|
const DAMAGE_CLASS = { physical: 'Phys', special: 'Spec', status: 'Stat' };
|
||||||
|
|
||||||
const idFromUrl = (u) => Number(u.replace(/\/$/, '').split('/').pop());
|
const idFromUrl = (u) => Number(u.replace(/\/$/, '').split('/').pop());
|
||||||
@ -141,11 +150,12 @@ export function MovesList(pokemonMoves, { versionGroupKey, gen = 9, genOfVg = ()
|
|||||||
const tmCell = method === 'machine' ? el('span', { class: 'moverow__tm' }) : null;
|
const tmCell = method === 'machine' ? el('span', { class: 'moverow__tm' }) : null;
|
||||||
let bodyFilled = false;
|
let bodyFilled = false;
|
||||||
|
|
||||||
const fillTm = () => {
|
const fillTm = async () => {
|
||||||
if (tmCell && !tmCell.textContent && m.data) {
|
if (!tmCell || m._tm != null || !m.data) return;
|
||||||
machineNumber(m.data, versionGroupKey).then((n) => {
|
const n = await machineNumber(m.data, versionGroupKey);
|
||||||
if (n) tmCell.textContent = n;
|
if (n) {
|
||||||
});
|
m._tm = n;
|
||||||
|
tmCell.textContent = n;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -167,7 +177,7 @@ export function MovesList(pokemonMoves, { versionGroupKey, gen = 9, genOfVg = ()
|
|||||||
const v = forGeneration(m.data, gen, genOfVg);
|
const v = forGeneration(m.data, gen, genOfVg);
|
||||||
fillMeta(meta, v);
|
fillMeta(meta, v);
|
||||||
fillBody(body, m.data, v);
|
fillBody(body, m.data, v);
|
||||||
fillTm();
|
await fillTm();
|
||||||
} catch {
|
} catch {
|
||||||
body.replaceChildren(el('span', { class: 'moverow__pending' }, 'Details unavailable.'));
|
body.replaceChildren(el('span', { class: 'moverow__pending' }, 'Details unavailable.'));
|
||||||
}
|
}
|
||||||
@ -182,13 +192,15 @@ export function MovesList(pokemonMoves, { versionGroupKey, gen = 9, genOfVg = ()
|
|||||||
el('span', { class: 'moverow__chev', 'aria-hidden': 'true' }, '▾'),
|
el('span', { class: 'moverow__chev', 'aria-hidden': 'true' }, '▾'),
|
||||||
);
|
);
|
||||||
|
|
||||||
list.append(el('div', { class: 'movecard' }, row, body));
|
const card = el('div', { class: 'movecard' }, row, body);
|
||||||
|
m._card = card;
|
||||||
|
list.append(card);
|
||||||
|
|
||||||
enrichers.push(async () => {
|
enrichers.push(async () => {
|
||||||
try {
|
try {
|
||||||
m.data = m.data || (await getMove(m.id));
|
m.data = m.data || (await getMove(m.id));
|
||||||
fillMeta(meta, forGeneration(m.data, gen, genOfVg));
|
fillMeta(meta, forGeneration(m.data, gen, genOfVg));
|
||||||
fillTm();
|
await fillTm();
|
||||||
} catch {
|
} catch {
|
||||||
meta.replaceChildren(el('span', { class: 'moverow__pending' }, '—'));
|
meta.replaceChildren(el('span', { class: 'moverow__pending' }, '—'));
|
||||||
}
|
}
|
||||||
@ -212,6 +224,14 @@ export function MovesList(pokemonMoves, { versionGroupKey, gen = 9, genOfVg = ()
|
|||||||
if (enriched) return;
|
if (enriched) return;
|
||||||
enriched = true;
|
enriched = true;
|
||||||
await mapLimit(enrichers, 6, (fn) => fn());
|
await mapLimit(enrichers, 6, (fn) => fn());
|
||||||
|
// TM/HM moves land in whatever order the API returned them; reorder
|
||||||
|
// to TM01, TM02 … once every number has resolved.
|
||||||
|
if (method === 'machine') {
|
||||||
|
moves
|
||||||
|
.slice()
|
||||||
|
.sort((a, b) => tmSortKey(a._tm) - tmSortKey(b._tm) || a.name.localeCompare(b.name))
|
||||||
|
.forEach((mm) => list.append(mm._card));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
group.addEventListener('toggle', () => group.open && runEnrich());
|
group.addEventListener('toggle', () => group.open && runEnrich());
|
||||||
if (method === 'level-up') runEnrich();
|
if (method === 'level-up') runEnrich();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user