remove confetti
This commit is contained in:
@@ -15,9 +15,7 @@
|
|||||||
*
|
*
|
||||||
* Signed in only: visitors get the sign-in modal over the page, and home if
|
* Signed in only: visitors get the sign-in modal over the page, and home if
|
||||||
* they dismiss it. Nothing about the quiz loads until they're signed in.
|
* they dismiss it. Nothing about the quiz loads until they're signed in.
|
||||||
*
|
|
||||||
* Finishing with every answer right sets off confetti — once, on finishing,
|
|
||||||
* not on revisiting the results later.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
@@ -43,13 +41,8 @@ import {
|
|||||||
} from "@/lib/quiz";
|
} from "@/lib/quiz";
|
||||||
import { QuizResultView } from "@/components/quiz/quiz-result-view";
|
import { QuizResultView } from "@/components/quiz/quiz-result-view";
|
||||||
import { CopyPageLinkButton } from "@/components/layout/copy-page-link-button";
|
import { CopyPageLinkButton } from "@/components/layout/copy-page-link-button";
|
||||||
import { Confetti } from "@/components/sadhna/confetti";
|
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
// The confetti's longest piece falls for 4.2s after a 0.5s delay; the layer
|
|
||||||
// is removed just after, so nothing lingers over the page once it's done.
|
|
||||||
const CONFETTI_MS = 5000;
|
|
||||||
|
|
||||||
type Stage =
|
type Stage =
|
||||||
| { kind: "loading" }
|
| { kind: "loading" }
|
||||||
| { kind: "intro"; card: QuizCard }
|
| { kind: "intro"; card: QuizCard }
|
||||||
@@ -64,13 +57,6 @@ export function QuizPlayer({ id }: { id: string }) {
|
|||||||
const [stage, setStage] = useState<Stage>({ kind: "loading" });
|
const [stage, setStage] = useState<Stage>({ kind: "loading" });
|
||||||
const [selected, setSelected] = useState<string[]>([]);
|
const [selected, setSelected] = useState<string[]>([]);
|
||||||
const [submitting, setSubmitting] = useState(false);
|
const [submitting, setSubmitting] = useState(false);
|
||||||
const [celebrate, setCelebrate] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!celebrate) return;
|
|
||||||
const t = setTimeout(() => setCelebrate(false), CONFETTI_MS);
|
|
||||||
return () => clearTimeout(t);
|
|
||||||
}, [celebrate]);
|
|
||||||
|
|
||||||
// Every new question starts with nothing selected.
|
// Every new question starts with nothing selected.
|
||||||
const goTo = (card: QuizCard, play: QuizPlay) => {
|
const goTo = (card: QuizCard, play: QuizPlay) => {
|
||||||
@@ -93,7 +79,6 @@ export function QuizPlayer({ id }: { id: string }) {
|
|||||||
async (card: QuizCard) => {
|
async (card: QuizCard) => {
|
||||||
const result = await quizApi.result(id);
|
const result = await quizApi.result(id);
|
||||||
setStage({ kind: "result", card, result });
|
setStage({ kind: "result", card, result });
|
||||||
return result;
|
|
||||||
},
|
},
|
||||||
[id],
|
[id],
|
||||||
);
|
);
|
||||||
@@ -133,12 +118,8 @@ export function QuizPlayer({ id }: { id: string }) {
|
|||||||
setSubmitting(true);
|
setSubmitting(true);
|
||||||
try {
|
try {
|
||||||
const next = await quizApi.answer(id, play.question.id, selected);
|
const next = await quizApi.answer(id, play.question.id, selected);
|
||||||
if (next.done) {
|
if (next.done) await showResult(card);
|
||||||
const result = await showResult(card);
|
else goTo(card, next);
|
||||||
if (result.total > 0 && result.score === result.total) {
|
|
||||||
setCelebrate(true);
|
|
||||||
}
|
|
||||||
} else goTo(card, next);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Most likely the question was already answered in another tab: pick up
|
// Most likely the question was already answered in another tab: pick up
|
||||||
// wherever the attempt actually is rather than leaving this one stuck.
|
// wherever the attempt actually is rather than leaving this one stuck.
|
||||||
@@ -329,14 +310,6 @@ export function QuizPlayer({ id }: { id: string }) {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{stage.kind === "result" && <QuizResultView result={stage.result} />}
|
{stage.kind === "result" && <QuizResultView result={stage.result} />}
|
||||||
|
|
||||||
{/* Full marks. Fixed over the viewport but pointer-events-none, so the
|
|
||||||
page stays usable while it falls, and unmounted once it's done. */}
|
|
||||||
{celebrate && (
|
|
||||||
<div className="pointer-events-none fixed inset-0 z-50" aria-hidden>
|
|
||||||
<Confetti />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user