Skip to content

Add first-view assignment confetti with one-time per-participant persistence#8

Open
Copilot wants to merge 5 commits intomainfrom
copilot/add-confetti-animation-first-view
Open

Add first-view assignment confetti with one-time per-participant persistence#8
Copilot wants to merge 5 commits intomainfrom
copilot/add-confetti-animation-first-view

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 17, 2026

Participants needed a celebratory confetti effect when opening their assignment, but only on the first view. This change adds a first-view-only confetti trigger in AssignmentView using canvas-confetti and persists view state per participant/game.

  • Assignment reveal celebration

    • Added canvas-confetti dependency.
    • Triggered confetti after assignment reveal animation in AssignmentView.
    • Uses dynamic import to avoid unnecessary eager bundle cost.
  • One-time behavior (per participant, per game)

    • Added local persistence key: assignment-viewed-${game.code}-${participant.id}.
    • Confetti is skipped when the key already exists.
    • Added in-memory guard to prevent duplicate firing during rerenders in the same session.
  • Behavior guardrails

    • Does not trigger confetti for already-confirmed assignments.
    • Confetti load failures are non-fatal (view remains fully functional).
  • E2E coverage for first-view marker

    • Added a focused E2E path that creates a protected game, opens a participant assignment link, and verifies the first-view marker is written.
const confettiStorageKey = `assignment-viewed-${game.code}-${participant.id}`

if (window.localStorage.getItem(confettiStorageKey) === 'true') return
if (currentParticipant.hasConfirmedAssignment) return

window.localStorage.setItem(confettiStorageKey, 'true')
void import('canvas-confetti').then(({ default: confetti }) =>
  confetti({ particleCount: 120, spread: 80, origin: { y: 0.65 } })
)

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • cdn.functions.azure.com
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node lib/install.js (dns block)
  • fonts.googleapis.com
    • Triggering command: /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1217/chrome-headless-shell-linux64/chrome-headless-shell /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1217/chrome-headless-shell-linux64/chrome-headless-shell --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Transl ules/.bin/sh HooksPath (dns block)
    • Triggering command: /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1217/chrome-headless-shell-linux64/chrome-headless-shell /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1217/chrome-headless-shell-linux64/chrome-headless-shell --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Transl odules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin/sh (dns block)
    • Triggering command: /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1217/chrome-headless-shell-linux64/chrome-headless-shell /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1217/chrome-headless-shell-linux64/chrome-headless-shell --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AvoidUnnecessaryBeforeUnloadCheckSync,BoundaryEventDispatchTracksNodeRemoval,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Transl k/_temp/ghcca-node/node/bin/git (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title [WIP] Add confetti animation using canvas-confetti for first assignment view Add first-view assignment confetti with one-time per-participant persistence Apr 17, 2026
Copilot AI requested a review from dsanchezcr April 17, 2026 18:54
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 17, 2026

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

OpenSSF Scorecard

PackageVersionScoreDetails
npm/canvas-confetti 1.9.4 🟢 3.9
Details
CheckScoreReason
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review⚠️ 1Found 2/12 approved changesets -- score normalized to 1
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Token-Permissions🟢 10GitHub workflow tokens follow principle of least privilege
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0

Scanned Files

  • package-lock.json

@github-actions
Copy link
Copy Markdown

Azure Static Web Apps: Your stage site is ready! Visit it here: https://lemon-island-0e99a7c0f-8.eastus2.7.azurestaticapps.net

@dsanchezcr dsanchezcr marked this pull request as ready for review April 17, 2026 19:12
Copilot AI review requested due to automatic review settings April 17, 2026 19:12
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a first-view-only confetti celebration to the participant assignment reveal in the React frontend, with a persisted “viewed” marker to ensure it only fires once per participant per game, plus an E2E test that verifies the marker is written.

Changes:

  • Trigger canvas-confetti via dynamic import after the assignment reveal animation, guarded by local persistence.
  • Persist a per-game/per-participant assignment-viewed-* key and add an in-memory guard to avoid duplicate firing during rerenders.
  • Add a Playwright E2E test that creates a protected game, opens a participant assignment link, and asserts the first-view marker is set.
Show a summary per file
File Description
src/components/AssignmentView.tsx Adds first-view confetti effect with localStorage persistence and session guard.
package.json Adds canvas-confetti dependency for the frontend celebration effect.
package-lock.json Locks canvas-confetti dependency resolution/integrity data.
e2e/app.spec.ts Adds E2E coverage to verify the first-view marker is persisted.

Copilot's findings

Comments suppressed due to low confidence (1)

src/components/AssignmentView.tsx:167

  • window.localStorage.setItem(...) can throw and currently isn’t guarded, which would surface as an unhandled effect error and could disrupt the assignment view. Consider wrapping the write in try/catch (and only setting lastTriggeredConfettiKeyRef after a successful write) to keep the view resilient.
    lastTriggeredConfettiKeyRef.current = confettiStorageKey
    window.localStorage.setItem(confettiStorageKey, 'true')

  • Files reviewed: 3/4 changed files
  • Comments generated: 1

Comment on lines +157 to +161
if (window.localStorage.getItem(confettiStorageKey) === 'true') {
return
}

if (currentParticipant.hasConfirmedAssignment) {
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

window.localStorage.getItem(...) can throw (e.g., storage disabled/quota exceeded). Since this effect is intended to be non-fatal (similar to the canvas-confetti import), please wrap the localStorage read in a try/catch (or use the existing useLocalStorage/safe-storage helper) so AssignmentView can’t error during reveal in hardened browser/privacy modes.

This issue also appears on line 165 of the same file.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown

Azure Static Web Apps: Your stage site is ready! Visit it here: https://icy-moss-044abd30f-8.eastus2.7.azurestaticapps.net

@github-actions
Copy link
Copy Markdown

Azure Static Web Apps: Your stage site is ready! Visit it here: https://icy-moss-044abd30f-8.eastus2.7.azurestaticapps.net

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a confetti animation using canvas-confetti when a participant views their assignment for the first time

3 participants