fix(playlists): the list shows the order the server holds

A read with the same rows in another order never reached the screen: a
revert to YouTube, a sync or another device left the old order showing, and
the next write put it back on the server. With no write out on any list the
screen now takes it, and the undo history built on the old order goes. Own
reorders still keep theirs. This replaces the one flag all lists shared after
a rollback, and shows a reorder accepted after its list was picked again.

Also what the fourth review found: a list's reorders go one after the other,
a toast Undo asks for its place once the writes out have landed, an accepted
reorder keeps fresher rows from the cache, and a Play all disabled by the last
row going no longer strands the focus.
This commit is contained in:
2026-11-03 03:01:17 +01:00
parent bbb4063362
commit 035ee937a0
4 changed files with 369 additions and 48 deletions
+10
View File
@@ -18,6 +18,16 @@ describe("useUndoable", () => {
expect(result.current.value).toEqual([10, 20]);
});
it("peeks at a value set in this tick, before it renders", () => {
const { result } = renderHook(() => useUndoable<number[]>([1]));
const { peek, set } = result.current;
act(() => {
set([1, 2]);
expect(peek()).toEqual([1, 2]);
});
expect(peek()).toEqual([1, 2]);
});
it("keeps the undo history through a rebase", () => {
const { result } = renderHook(() => useUndoable<number[]>([1]));
act(() => result.current.set([1, 2]));
+5
View File
@@ -16,6 +16,8 @@ import { useLatest } from "./useLatest";
// Render never reads the ref: a compiled component would otherwise memoize a stale value.
export interface Undoable<T> {
value: T;
/** The value as of NOW, with a `set` not rendered yet, for code that runs after an await. */
peek: () => T;
set: (next: T) => void;
reset: (value: T) => void;
rebase: (map: (value: T) => T) => void;
@@ -110,8 +112,11 @@ export function useUndoable<T>(
setH(over);
}, []);
const peek = useCallback(() => ref.current.present, []);
return {
value: h.present,
peek,
set,
reset,
rebase,