fix(player): marks are weighed when answered, lit and pressed hold under the pointer, and Restart is one glyph
The watched toggle weighed its own click at click time against marks stamped when the server answered, so the late answer of its previous click overruled the newer one; it now holds its word while any of its writes is on the way, is stamped at the answer, and drops a refused write. The hosts return the write. In a live search the feed's own answered writes stand down over the rows, which carry the marks, so a newer mark from the related list reaches a card the feed touched earlier. A lit mode cycle got the hover layer, and a variant's hover colour outranked the pressed and lit colours: the state layer stands down on [data-lit] and those colours are important. The menus' Play from the beginning wears RotateCcw like the card's Restart, Reset wears Eraser and Redownload the retry arrow (DESIGN decision log). Tests pin the toggle's orders, the Watch later mark at its call sites, the live-search overrides, the hover exemptions and the menu glyphs.
This commit is contained in:
@@ -307,7 +307,10 @@ function PlaylistDetail() {
|
||||
});
|
||||
const detail = detailQuery.data;
|
||||
// Which kind of list an item write goes to (the Watch later list's items are the bookmark):
|
||||
// the rail's list knows every one, the open detail the one on screen.
|
||||
// the rail's list knows every one, the open detail the one on screen. Only a user list's rows are
|
||||
// removed or moved from here today (Watch later offers neither), so it reads "user" — looked up
|
||||
// all the same, so no write here takes the kind for granted. A move INTO Watch later passes the
|
||||
// rail's own row as its target.
|
||||
const listRef = (id: number) => ({
|
||||
id,
|
||||
kind: playlists.find((p) => p.id === id)?.kind ?? (detail?.id === id ? detail.kind : undefined),
|
||||
@@ -623,7 +626,8 @@ function PlaylistDetail() {
|
||||
}
|
||||
|
||||
function playerState(id: string, status: VideoStatus) {
|
||||
writeVideoState(qc, id, status)
|
||||
const write = writeVideoState(qc, id, status);
|
||||
write
|
||||
.then(() => {
|
||||
// Every cached list, not `qk.playlist(selectedId)`: the player may have been launched from a
|
||||
// list that is no longer the selected one (see `playing`), and that list holds the row whose
|
||||
@@ -633,6 +637,7 @@ function PlaylistDetail() {
|
||||
})
|
||||
// No catch used to mean an unhandled rejection and nothing said.
|
||||
.catch((e: unknown) => notifyActionError(e, t("errors.writeFailed.videoState")));
|
||||
return write;
|
||||
}
|
||||
|
||||
// Stable identity: PlayerModal's keydown effect depends on it, so a fresh closure
|
||||
|
||||
Reference in New Issue
Block a user