feat(whiteboard): add PNG and PDF export functionality (#1915) - #1939
feat(whiteboard): add PNG and PDF export functionality (#1915)#1939Shriraj888 wants to merge 2 commits into
Conversation
|
@Shriraj888 is attempting to deploy a commit to the durdana3105's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughChangesWhiteboard export
Session callback typing
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant WhiteboardToolbar
participant CanvasExportHandlers
participant exportUtils
participant Browser
participant jsPDF
WhiteboardToolbar->>CanvasExportHandlers: Select PNG or PDF export
CanvasExportHandlers->>exportUtils: Export canvas with generated filename
exportUtils->>Browser: Trigger PNG download
exportUtils->>jsPDF: Add canvas image and save PDF
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/hooks/useSessions.ts (1)
183-192: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse concrete realtime payload types.
payload: anydisables type checking for both broadcast messages. Define payload types for thetypingandactivityevents. Let.subscribeinferstatusor use the SDK status type instead of widening it tostring. TypeScript documents thatanyallows unchecked property access, and Supabase provides typed callback contracts for these APIs. (typescriptlang.org)- .on("broadcast", { event: "typing" }, ({ payload }: { payload: any }) => { + .on("broadcast", { event: "typing" }, ({ payload }: { payload: TypingPayload }) => { ... - .on("broadcast", { event: "activity" }, ({ payload }: { payload: any }) => { + .on("broadcast", { event: "activity" }, ({ payload }: { payload: ActivityPayload }) => { ... - .subscribe(async (status: string) => { + .subscribe(async (status) => {Verify these callback types against the pinned
@supabase/supabase-js2.102.1declarations before adding SDK-specific imports.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/hooks/useSessions.ts` around lines 183 - 192, Replace the any payload annotations in the typing and activity handlers within useSessions with concrete payload types matching each event’s fields, preserving their existing behavior. Remove the explicit string annotation from the subscribe callback so the Supabase SDK infers its status type, or use the compatible SDK status type after verifying the pinned `@supabase/supabase-js` declarations.src/components/Whiteboard/exportUtils.test.ts (1)
31-48: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMock and assert the offscreen canvas.
getExportCanvasDataURLcreates a separate canvas withdocument.createElement("canvas"). This setup only configuresdummyCanvas, so the test does not prove that the offscreen path fills the background or draws the source canvas. Return a mocked offscreen canvas and assertfillRect,drawImage, and itstoDataURLcall.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/Whiteboard/exportUtils.test.ts` around lines 31 - 48, Update the getExportCanvasDataURL test setup to mock the canvas returned by document.createElement("canvas"), including its 2D context, fillRect, drawImage, and toDataURL methods. In the test, assert the offscreen context fills the background and draws dummyCanvas, and verify the offscreen canvas toDataURL call returns the expected data URL.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/Whiteboard/exportUtils.ts`:
- Around line 7-13: Update getExportCanvasDataURL to validate that the source
canvas has non-zero dimensions before creating the offscreen canvas, rejecting
invalid dimensions consistently for PNG and PDF export callers. Add a test
covering zero-width or zero-height canvases and the resulting PNG export
failure.
---
Nitpick comments:
In `@src/components/Whiteboard/exportUtils.test.ts`:
- Around line 31-48: Update the getExportCanvasDataURL test setup to mock the
canvas returned by document.createElement("canvas"), including its 2D context,
fillRect, drawImage, and toDataURL methods. In the test, assert the offscreen
context fills the background and draws dummyCanvas, and verify the offscreen
canvas toDataURL call returns the expected data URL.
In `@src/hooks/useSessions.ts`:
- Around line 183-192: Replace the any payload annotations in the typing and
activity handlers within useSessions with concrete payload types matching each
event’s fields, preserving their existing behavior. Remove the explicit string
annotation from the subscribe callback so the Supabase SDK infers its status
type, or use the compatible SDK status type after verifying the pinned
`@supabase/supabase-js` declarations.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 6e0d67a6-a800-46ba-8e43-1458989f65f4
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (6)
package.jsonsrc/App.tsxsrc/components/Whiteboard/Canvas.tsxsrc/components/Whiteboard/exportUtils.test.tssrc/components/Whiteboard/exportUtils.tssrc/hooks/useSessions.ts
💤 Files with no reviewable changes (1)
- src/App.tsx
|
@durdana3105 Could you please review my PR when you get a chance? I'd really appreciate your feedback. |
📌 Description
During study sessions, users create detailed notes and diagrams on the Whiteboard. Previously, there was no way to save or export the canvas state after a session ended.
This PR implements Export to PNG and Export to PDF buttons directly on the Whiteboard toolbar, allowing users to save their whiteboard diagrams locally in their preferred format.
✨ Key Changes
exportUtils.ts):getExportCanvasDataURL(): Synthesizes canvas drawing onto an offscreen canvas pre-filled with the dark slate background (#020617), preserving dark slate background styling and eraser stroke visibility.exportCanvasToPNG(): Encodes canvas to PNG and triggers browser file download.exportCanvasToPDF(): UsesjsPDFto generate a custom-dimensioned PDF matching the canvas aspect ratio and triggers browser file download.Canvas.tsx):Download,FileText) to the top toolbar.sonner(toast.success&toast.error).package.json):jspdfdependency for client-side PDF document generation.exportUtils.test.ts):🧪 How to Test
/room/:id)..pngfile downloads matching the canvas drawing with the dark background..pdfdocument downloads containing the canvas image.📸 Automated Test Status
npx vitest run src/components/Whiteboard/(10/10 tests passed)npm run typecheck(Passed with zero errors)Closes #1915
Summary by CodeRabbit
New Features
Bug Fixes