diff --git a/frontend/sortof-app.jsx b/frontend/sortof-app.jsx index 09aa68e..6827275 100644 --- a/frontend/sortof-app.jsx +++ b/frontend/sortof-app.jsx @@ -145,67 +145,47 @@ function WsidLink({ wsid, children, className }) { ); } -// Snapshot the fields needed to diff against the next sort/resort. Called -// before each fetch fires so the snapshot captures "what the user saw -// before this action". Polling-mid-flight ticks intentionally don't snapshot -// (would erase the prior visible state on every 2.5s update). -function snapshotForDiff(src) { - if (!src) return null; - return { - SORTED_ORDER: [...(src.SORTED_ORDER || [])], - MOD_DB: (src.MOD_DB || []).map(m => ({ modId: m.modId, wsid: m.wsid, name: m.name })), - MODS_LINE: src.MODS_LINE || '', - WORKSHOP_ITEMS_LINE: src.WORKSHOP_ITEMS_LINE || '', - }; -} - -function computeDiff(prev, curr) { - if (!prev || !curr) return null; - const prevSorted = prev.SORTED_ORDER || []; - const currSorted = curr.SORTED_ORDER || []; - const prevSet = new Set(prevSorted); - const currSet = new Set(currSorted); - const added = currSorted.filter(id => !prevSet.has(id)); - const removed = prevSorted.filter(id => !currSet.has(id)); - const prevPos = new Map(prevSorted.map((id, i) => [id, i])); +// Compare the wsids the user pasted (input order, deduped) against the wsids +// in WORKSHOP_ITEMS_LINE (sort order). Always available — no "previous sort" +// required. Surfaces drops (banned / missing mod.info / unknown / collection +// IDs that expanded), additions (collection expansion, branch picks), and +// position changes. +function computeDiff(inputWsids, outputWsids) { + if (!inputWsids || !outputWsids) return null; + const inSet = new Set(inputWsids); + const outSet = new Set(outputWsids); + const added = outputWsids.filter(w => !inSet.has(w)); + const removed = inputWsids.filter(w => !outSet.has(w)); + const inPos = new Map(inputWsids.map((w, i) => [w, i])); const movers = []; - currSorted.forEach((id, ci) => { - if (!prevSet.has(id)) return; - const pi = prevPos.get(id); - if (pi !== ci) movers.push({ id, from: pi, to: ci, delta: ci - pi }); + outputWsids.forEach((w, oi) => { + if (!inSet.has(w)) return; + const ii = inPos.get(w); + if (ii !== oi) movers.push({ wsid: w, from: ii, to: oi, delta: oi - ii }); }); movers.sort((a, b) => Math.abs(b.delta) - Math.abs(a.delta)); - const prevWsl = (prev.WORKSHOP_ITEMS_LINE || '').replace(/;+$/, '').split(';').filter(Boolean); - const currWsl = (curr.WORKSHOP_ITEMS_LINE || '').replace(/;+$/, '').split(';').filter(Boolean); - const prevWsidPos = new Map(prevWsl.map((w, i) => [w, i])); - const wsidMovers = []; - currWsl.forEach((w, ci) => { - const pi = prevWsidPos.get(w); - if (pi !== undefined && pi !== ci) wsidMovers.push({ wsid: w, from: pi, to: ci }); - }); - wsidMovers.sort((a, b) => Math.abs(b.to - b.from) - Math.abs(a.to - a.from)); - return { added, removed, movers, wsidMovers }; + return { added, removed, movers }; } -function DiffPanel({ prev, curr, onClose }) { - const diff = computeDiff(prev, curr); +function DiffPanel({ inputWsids, outputWsids, onClose }) { + const diff = computeDiff(inputWsids, outputWsids); if (!diff) { return (