fix(playlists): an Undo puts a row back after its old neighbour, not at a stale index
A raw index recorded at removal drifted once anything changed before the Undo. Both lists now read the list fresh and re-insert each row after the row that preceded it (lib/reinsert). A failed watched toggle in a Plex playlist also puts the row's state back: its local copy was never re-seeded.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
/** Where removed rows go back when their Undo comes LATER than the removal.
|
||||
*
|
||||
* A raw index recorded at removal time drifts: an add or a reorder landing in between (another tab,
|
||||
* the rail, the player) shifts everything after it, and the row came back one or more places off
|
||||
* (E28 review C4). So each removed row goes back right after the row that preceded it in the list
|
||||
* it was removed from — its neighbour, looked up in the list as it stands NOW — or at the start when
|
||||
* it was first or no earlier neighbour is left. Rows already back in the list are skipped (the
|
||||
* server's add is idempotent and would leave them where they are).
|
||||
*
|
||||
* @param before the list's ids when the rows were removed, in stored order
|
||||
* @param removed the ids taken out
|
||||
* @param now the list's ids at Undo time, in stored order
|
||||
* @returns the ids to add back and, paired one to one, the index each lands at — ascending, the
|
||||
* shape the server's insert takes (each index counts the rows put back before it). */
|
||||
export function reinsertAt(
|
||||
before: readonly string[],
|
||||
removed: readonly string[],
|
||||
now: readonly string[],
|
||||
): { keys: string[]; positions: number[] } {
|
||||
const out = new Set(removed);
|
||||
const list = [...now];
|
||||
const placed: string[] = [];
|
||||
for (let i = 0; i < before.length; i++) {
|
||||
const id = before[i]!;
|
||||
if (!out.has(id) || now.includes(id)) continue;
|
||||
let at = 0;
|
||||
for (let j = i - 1; j >= 0; j--) {
|
||||
const k = list.indexOf(before[j]!);
|
||||
if (k >= 0) {
|
||||
at = k + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
list.splice(at, 0, id);
|
||||
placed.push(id);
|
||||
}
|
||||
const keys = placed.map((id) => ({ id, at: list.indexOf(id) })).sort((a, b) => a.at - b.at);
|
||||
return { keys: keys.map((k) => k.id), positions: keys.map((k) => k.at) };
|
||||
}
|
||||
Reference in New Issue
Block a user