Add first-view assignment confetti with one-time per-participant persistence#8
Add first-view assignment confetti with one-time per-participant persistence#8
Conversation
Agent-Logs-Url: https://github.com/Azure-Samples/DevOpsEngineerPersona/sessions/62618c0c-2d03-411b-acf4-343fdc49d0af Co-authored-by: dsanchezcr <10506023+dsanchezcr@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Azure-Samples/DevOpsEngineerPersona/sessions/62618c0c-2d03-411b-acf4-343fdc49d0af Co-authored-by: dsanchezcr <10506023+dsanchezcr@users.noreply.github.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.OpenSSF Scorecard
Scanned Files
|
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://lemon-island-0e99a7c0f-8.eastus2.7.azurestaticapps.net |
There was a problem hiding this comment.
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-confettivia 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 settinglastTriggeredConfettiKeyRefafter 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
| if (window.localStorage.getItem(confettiStorageKey) === 'true') { | ||
| return | ||
| } | ||
|
|
||
| if (currentParticipant.hasConfirmedAssignment) { |
There was a problem hiding this comment.
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.
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://icy-moss-044abd30f-8.eastus2.7.azurestaticapps.net |
|
Azure Static Web Apps: Your stage site is ready! Visit it here: https://icy-moss-044abd30f-8.eastus2.7.azurestaticapps.net |
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
AssignmentViewusingcanvas-confettiand persists view state per participant/game.Assignment reveal celebration
canvas-confettidependency.AssignmentView.One-time behavior (per participant, per game)
assignment-viewed-${game.code}-${participant.id}.Behavior guardrails
E2E coverage for first-view marker
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/home/REDACTED/work/_temp/ghcca-node/node/bin/node node lib/install.js(dns block)fonts.googleapis.com/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)/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)/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: