Roll back only the decision's own Quest log entry and send stale-card decisions
CI / ci (push) Failing after 1m55s
CI / ci (pull_request) Successful in 2m43s

A refused Try it now removes the Quest log entry it tagged when it added
it, so a read of the Quest log that landed during the decision is kept,
and reads the Quest log again since the decision may have been saved.

A decision is sent for the card thrown out even when a read of the deck
took it off during the exit, so Retry on that refusal posts the decision
again instead of failing before sending it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-07 02:53:09 -04:00
co-authored by Claude Opus 5.5
parent 6c105416a9
commit 0ea1c218ea
3 changed files with 82 additions and 37 deletions
+5 -4
View File
@@ -17,6 +17,7 @@ import {
useQuestLog,
useStartBatch,
type Choice,
type SideQuest,
} from './api.ts'
import { DeckCard, DECK_DEPTH, type SwipeHandlers } from './DeckCard.tsx'
import {
@@ -152,8 +153,8 @@ export function DiscoverPage() {
// send records a decision. A refused one puts the card back; a saved one
// that started a replenish batch follows its job.
const send = useCallback(
(variables: { id: string; choice: Choice }) => {
leaving.current = variables.id
(variables: { quest: SideQuest; choice: Choice }) => {
leaving.current = variables.quest.id
mutateDecision(variables, {
onSuccess: (replenishJobId) => {
if (replenishJobId !== null) setBatchJobId(replenishJobId)
@@ -172,7 +173,7 @@ export function DiscoverPage() {
[mutateDecision],
)
const submit = useCallback(
(variables: { id: string; choice: Choice }) => {
(variables: { quest: SideQuest; choice: Choice }) => {
if (lock()) send(variables)
},
[lock, send],
@@ -217,7 +218,7 @@ export function DiscoverPage() {
() => {
// The Quest log pill is missing while the Quest log fails to load.
if (choice === 'try' && !reduced && questLogRef.current !== null) bump(questLogRef.current)
send({ id: top.id, choice })
send({ quest: top, choice })
},
(error: unknown) => {
if (!isAbort(error)) throw error