From ac11c3d60641ead881b15aa4c41c5b279f1fbf47 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 9 Jun 2026 18:51:56 +0000 Subject: [PATCH] feat: add roulette spinner auto-select to the results page Adds a 'Spin for me' option over the 3-5 result cards: the highlight travels across the picks with a decelerating 2-4s step sequence (spin-plan.ts), lands on a random book, and offers accept/respin. Accepting reuses the existing selection tracking and confirmation screen. Falls back to an instant reveal under prefers-reduced-motion, and puts the previously unused book-spin pulse to work on the highlighted card. Completes TODO task 12. https://claude.ai/code/session_01T3Bf7bT36EKqybyL4X2uKQ --- TODO.md | 44 +++++++------ .../app/features/result/result.component.html | 66 ++++++++++++++++++- .../app/features/result/result.component.ts | 55 +++++++++++++++- .../src/app/features/result/spin-plan.spec.ts | 56 ++++++++++++++++ frontend/src/app/features/result/spin-plan.ts | 35 ++++++++++ goodreads_tbr_recommendation_spec.md | 2 +- 6 files changed, 233 insertions(+), 25 deletions(-) create mode 100644 frontend/src/app/features/result/spin-plan.spec.ts create mode 100644 frontend/src/app/features/result/spin-plan.ts diff --git a/TODO.md b/TODO.md index 67260a0..9211a50 100644 --- a/TODO.md +++ b/TODO.md @@ -10,27 +10,6 @@ > Known future work, not yet planned. -### 12. Roulette / spinner selection - -Depends on: 11 - -> Deferred. Manual selection (tap a book → detail modal → confirm) is implemented and -> covers the "select a book" outcome. The spec's roulette spinner is an optional, -> additive way to pick between the 3–5 results and has not been built. A `book-spin` -> CSS keyframe exists in `styles.css` but is currently unused. - -#### Tasks - -- Implement roulette spinner component (2–4s decelerate easing) over the 3–5 results -- Respect `prefers-reduced-motion` (instant reveal fallback) -- Allow respin and accept -- Wire to the existing result reveal - -#### Done when - -- Spinner resolves to a single book with correct motion behaviour -- Respin and accept work on mobile - ### 16. Book status: mark in progress / completed Depends on: 11 @@ -143,6 +122,29 @@ Depends on: 1 > Merged and verified. +### 12. Roulette / spinner selection + +Depends on: 11 + +> Implemented as an optional "Spin for me" control on the results page rather than a +> separate spinner screen. The highlight travels across the existing result cards with +> decelerating steps (~2–3s, within the brand's 2–4s spinner window, via +> `spin-plan.ts`), lands on a random pick, and reuses the unused `book-spin` pulse. +> Manual selection remains the primary path. + +#### Tasks + +- [x] Roulette spin over the 3–5 results (2–4s decelerating step sequence) +- [x] Respect `prefers-reduced-motion` (instant reveal fallback) +- [x] Respin and accept from the spin result panel +- [x] Wired to the existing result reveal and accept/confirmation flow +- [x] Unit tests for the spin schedule (`spin-plan.spec.ts`) + +#### Done when + +- [x] Spinner resolves to a single book with correct motion behaviour +- [x] Respin and accept work on mobile + ### 19. Quiz flow improvements Depends on: 11 diff --git a/frontend/src/app/features/result/result.component.html b/frontend/src/app/features/result/result.component.html index 762efdf..18d7faf 100644 --- a/frontend/src/app/features/result/result.component.html +++ b/frontend/src/app/features/result/result.component.html @@ -72,6 +72,63 @@

+ + @if (picks().length > 1) { +
+ @if (!spunBook()) { + + } +
+ @if (spunBook() && !spinning()) { +
+
+

+ The spinner chose +

+

+ {{ spunBook()!.title }} +

+ @if (spunBook()!.author) { +

+ {{ spunBook()!.author }} +

+ } +
+
+ + +
+
+ } +
+
+ } +