Repository navigation
Native iOS app: Timer and typed Crossfire - #132
Conversation
The website's formats, speeches and signals in a full-screen ring like the live round in mock 05. The clock keeps start timestamps instead of counting ticks, so it shows the right time after the app comes back from the background, and a gap that crosses both thresholds sounds only time up. The beeps are bundled WAVs generated by scripts/render-timer-sounds.ts from the website's synth, played with expo-audio, with an expo-haptics tap on each signal. expo-keep-awake keeps the screen on while a speech runs. The web preview records the signals instead, and the screenshot run checks them on Playwright's clock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Crossfire as the website's CrossfirePage in its typed mode: the same setup, the shared reducer and schemas from @debatelab/core, and the crossfire and crossfireSignal requests with the website's bodies, Ask model settings, debate context, 75 s and 5 s deadlines and response checks. The round runs full screen with its clock read from the end timestamp, keeps for the session if the student leaves it (a request cut off by leaving becomes one to retry), and is saved to crossfires in its debate when the debrief arrives. The debrief reads as a document in #130's style. Voice rounds need the development build, so the website's voice switch shows disabled with a note. The screenshot run fakes every turn, signal and debrief in the run's language. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In Hungarian, "Munkamenet befejezése" squeezed the round's resolution to two words; the button now wraps its label. On iPad the speech chips and the signals card sat left of the centred ring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Note 🎁 Summarized by CodeRabbit Free
Comment |
The website shows crossfire.charactersRemaining under the turn field. It was left out because plural strings did not render on Hermes; #129's Intl.PluralRules polyfill fixes that, so the composer now shows it beside its label, and the screenshot script checks it reads as a number. The app guide notes that the Crossfire setup shows one-off mode through WorkingIn, as the website's CurrentDebateStrip does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pausing as the Timer turned from 1:01 to 1:00 moved its last reading past the threshold without a decision, so that speech never beeped. Time left only falls while the clock runs, so every fall is now checked (signalFor in timer.ts); only a fresh clock after a reset or another speech is skipped. A Crossfire turn or debrief read its model settings and Library context before its 75 s deadline and outside its abort, so a stalled read kept the turn pending past 75 s and leaving could not cancel it. withTurnDeadline now starts the deadline first and passes one signal through the reads and the request. A finished round was saved from the state when the debrief was asked for, so a coaching signal that arrived meanwhile was shown but not saved. The round is now saved from the state it reaches, as CrossfirePage does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The shared request helper now waits for the session read only until the deadline or the caller's abort, so a stalled token refresh can't hold a Crossfire turn or any other request past its timeout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A request whose caller had already left still read the session, and if that read failed nobody handled the error. Check the abort first, and let untilAborted absorb a read it no longer waits for. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Codex review r3 at 595cbdc: 1 finding (Medium): a request cancelled before it started still read the session, and a failing read leaked an unhandled rejection. Fixed in 8f05fe3 (abort checked before the read; untilAborted absorbs a read it no longer waits for; regression test fails without the fix). Merge resolution and locale key sets checked clean. Local: npm run verify green (301 vitest, 30 smoke), mobile typecheck, eslint, knip pass. CI is billing-blocked; these are local results. Codex r4 next. |
…/05a-timer-crossfire # Conflicts: # apps/mobile/AGENTS.md # apps/mobile/scripts/screenshots.ts # apps/mobile/src/app/_layout.tsx
|
Codex review r4 at 8f05fe3 (gpt-6.1-sol, high): no findings; probes confirmed r3's unhandled rejection is gone. Then merged feat/native-ios (with #133 Flowchart) as f130458: conflicts in _layout.tsx, screenshots.ts and apps/mobile/AGENTS.md, each resolved by keeping both sides. Local at f130458: npm run verify green (307 vitest, 30 smoke), mobile typecheck, eslint, knip pass. Codex r5 on the merge resolution next. |
|
Codex review r5 at f130458 (merge of feat with #133): no findings; route registrations, Prepare/Practice navigation, screenshot sections and docs checked; en/es/hu keep identical sets of 174 mobile.* keys. Merged-head screenshot run (iphone-light-en, staging): 61 shots incl. Practice, Timer, Crossfire and Flowchart. Merging into feat/native-ios. Not provable here: timer sound, haptics, keep-awake (Adam's phone). |




This PR adds the Practice tab's Timer and typed Crossfire. Targets
feat/native-ios.Timer works like the website's TimerPage:
apps/mobile/assets/sounds). expo-haptics taps with each beep, and expo-keep-awake keeps the screen on while a speech runs. Muting keeps the tap.TODO(live-activity)marker where it goes.timer.test.tscovers a 90 s gap with no ticks, pausing, and both thresholds.Crossfire, typed mode:
postFunctiongained an optional timeout to support those deadlines.@debatelab/core/crossfire.crossfiresthe way the website'srecordResultdoes. One-off rounds aren't saved, as on the website.Matches the website rather than the brief:
Checks, run locally on Node 22 because GitHub Actions starts no jobs on this account (billing):
npm run verifyexits 0: 293 Vitest, 333 Deno and 30 Chromium smoke tests.expo-audio,expo-hapticsandexpo-keep-awake, all in Expo Go's bundled modules.Live on the staging seed Pro account, one typed round:
neutral, then deleted (0 → 1 → 0).Not proven here: sound, haptics, keep-awake and the native modal on a real iPhone. Those are for Adam's phone.
🤖 Generated with Claude Code