-
Notifications
You must be signed in to change notification settings - Fork 14
✨(print) add "Print" button in messages context menu #518
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
📝 WalkthroughWalkthroughAdds "Print" translations to en-US, fr-FR, and nl-NL and implements a new printing flow: a usePrint hook that formats message metadata and body into a printable HTML document, plus a UI action that invokes print from thread message actions. Changes
Sequence DiagramsequenceDiagram
actor User
participant ThreadMessageActions as Thread Message Actions
participant UsePrint as usePrint Hook
participant DOM as Document DOM
participant PrintWindow as Print Window
participant Browser as Browser Print
User->>ThreadMessageActions: Click "Print" action
ThreadMessageActions->>UsePrint: print(message)
UsePrint->>DOM: Query iframe `#thread-message-{id} .thread-message__body`
DOM-->>UsePrint: Return iframe / innerHTML
UsePrint->>UsePrint: Build header (From, To, Cc, Bcc, Date, Subject) and sanitize HTML
UsePrint->>PrintWindow: window.open()
UsePrint->>PrintWindow: write HTML document (styles + content) and close()
PrintWindow->>Browser: onload -> window.print()
Browser->>PrintWindow: Print completed
PrintWindow->>UsePrint: Window closed
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/frontend/src/features/message/use-print.tsx`:
- Around line 34-36: The headerRows construction currently interpolates
unescaped h.value (and message.subject is interpolated into the <title>) which
can lead to XSS; add an HTML-escape utility (e.g., escapeHtml) and use it when
rendering header values in the map for headerRows (replace h.value with
escapeHtml(h.value ?? '')) and when inserting message.subject into the title
(use escapeHtml(message.subject ?? '')). Also ensure formatContact continues to
be safe or apply escapeHtml to its output as well so all user-controlled strings
are escaped before being placed into the template.
🧹 Nitpick comments (3)
src/frontend/src/features/message/use-print.tsx (3)
61-62: Silent failure when popup is blocked.If the browser blocks the popup,
window.open('')returnsnulland the function silently returns. Consider providing user feedback (e.g., a toast notification) so users know why printing didn't work.
66-67: Print window may not close on all browsers/user actions.The
afterprintevent listener closes the window, but this event may not fire if the user cancels the print dialog in some browsers. Additionally, relying ononloadto triggerprint()is generally reliable, but the ordering withaddEventListenerforafterprintcould be cleaner.Consider a small timeout fallback or accept the current behavior as acceptable for this use case.
14-17: DOM coupling via hardcoded selector.The hook relies on a specific DOM structure (
#thread-message-${message.id} .thread-message__body) to find the iframe. This creates tight coupling between this hook and the thread-message component's internal structure. If the class name or structure changes, this will silently fail (returning empty body).Consider documenting this dependency or passing the body content as a parameter to make the contract explicit.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.