Skip to content

Added click to copy button#3

Open
keyurchotaliyaa wants to merge 1 commit into
Devanshukoli:mainfrom
keyurchotaliyaa:copy-to-clipboard
Open

Added click to copy button#3
keyurchotaliyaa wants to merge 1 commit into
Devanshukoli:mainfrom
keyurchotaliyaa:copy-to-clipboard

Conversation

@keyurchotaliyaa

@keyurchotaliyaa keyurchotaliyaa commented May 27, 2026

Copy link
Copy Markdown

🚀 Feature Added: Copy Meme to Clipboard

📌 Description

Added a "Copy to Clipboard" button below the generated meme image.
Now users can quickly copy the generated meme image and paste/use it anywhere (WhatsApp, Discord, Notes, etc.).

✨ Changes Made

  • Added a new Copy to Clipboard button below meme image.
  • Implemented clipboard functionality using browser Clipboard API.
  • Improved user experience for sharing memes instantly.

🛠️ Tech Used

  • React
  • JavaScript Clipboard API

📷 Screenshots

copy-to-clipboard button Button Clicked

✅ Result

Users can now:

  1. Generate meme
  2. Click Copy to Clipboard
  3. Paste meme anywhere directly

Summary by CodeRabbit

  • New Features
    • Added a "Copy image to clipboard" button enabling users to copy rendered memes directly to their clipboard with ease
    • Real-time status feedback messages display progress and outcomes during the copy operation
    • Enhanced UI with improved styling for copy controls and status messaging

Review Change Stack

@vercel

vercel Bot commented May 27, 2026

Copy link
Copy Markdown

@keyurchotaliyaa is attempting to deploy a commit to the devanshukoli's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The PR adds clipboard-copy functionality for the rendered meme image. The feature loads the image with canvas rendering, applies text overlays, and attempts to write the result to the clipboard via the modern Clipboard API with progressive fallbacks to raw blob copy and URL text copy. A new button and status message provide user feedback.

Changes

Clipboard Copy Feature

Layer / File(s) Summary
Copy handler and state management
components/Main.jsx
copyStatus state tracks copy progress. handleCopyImageClick renders the meme to canvas, attempts clipboard write via ClipboardItem, then falls back to copying raw blob and URL text if needed, updating status and clearing it via timeouts.
Copy button UI and styling
components/Main.jsx, src/index.css
Copy button with disabled state during copying, conditional status message display, and new CSS classes for button appearance, disabled state, layout, and status typography.

Sequence Diagram

sequenceDiagram
  participant User
  participant Handler as handleCopyImageClick
  participant Canvas as Canvas Render
  participant ClipboardAPI as navigator.clipboard
  participant Fallback1 as Raw Blob Copy
  participant Fallback2 as URL Text Copy
  User->>Handler: Click copy button
  Handler->>Canvas: Load image + render text to canvas
  Canvas-->>Handler: PNG blob
  Handler->>ClipboardAPI: Write ClipboardItem with PNG
  alt Success
    ClipboardAPI-->>Handler: Clipboard written
    Handler->>Handler: Set copyStatus to success
  else ClipboardItem not supported
    Handler->>Fallback1: Attempt raw blob copy
    alt Blob copy succeeds
      Fallback1-->>Handler: Image copied
      Handler->>Handler: Set copyStatus to success
    else Blob unavailable
      Handler->>Fallback2: Copy URL or use textarea
      Fallback2-->>Handler: Text copied
      Handler->>Handler: Set copyStatus to fallback
    end
  end
  Handler->>Handler: Clear status after timeout
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A fuzzy meme now finds the clipboard's keep,
Canvas strokes and fallback chains run deep,
With buttons bright and status clear to see,
Copy rendered joy with fallback harmony!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main feature addition—a click-to-copy button for meme images—which aligns with the primary change across both modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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 `@components/Main.jsx`:
- Line 46: The disabled-state string checked elsewhere does not match the value
set by setCopyStatus; update the code so the status string is consistent: either
change the call to setCopyStatus in the copy handler to use 'Copying...' instead
of 'Copying meme...' or change the conditional that checks copy status (the
comparison against 'Copying...') to compare against 'Copying meme...'; locate
the setCopyStatus call and the button-disabled check to make both use the same
exact string so the button correctly disables during copy.
- Line 191: The copy feedback div currently rendered by Main.jsx using the
copyStatus variable is visual-only; update the element that renders {copyStatus}
(the div with className "copy-status") to be an accessible live region by adding
appropriate attributes such as role="status" and aria-live="polite" (and
optionally aria-atomic="true") so screen readers will announce success/fallback
messages when copyStatus changes.
- Around line 143-155: Wrap the
navigator.clipboard.writeText(memeInputs.imageUrl) call in a try/catch and on
rejection set an explicit failure message via setCopyStatus (e.g., "Could not
copy combined meme (clipboard denied). Image URL copied instead.") and continue
to the fallback; when using document.execCommand('copy') inspect its boolean
return value and set failure status if it returns false. Normalize the
copy-state strings so the button disable condition matches (either change
setCopyStatus to use 'Copying...' or change the button check to 'Copying
meme...') and ensure the timeout-clearing behavior remains. Finally, make the
status container (className "copy-status") an accessible live region (add
aria-live="polite" or role="status") so assistive tech announces updates.
🪄 Autofix (Beta)

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

Run ID: a952e8c0-5a93-43c9-98be-6c7b65bc98d1

📥 Commits

Reviewing files that changed from the base of the PR and between b445bb3 and 1fa2340.

📒 Files selected for processing (2)
  • components/Main.jsx
  • src/index.css

Comment thread components/Main.jsx

const handleCopyImageClick = async () => {
// Attempt to render the meme (image + top/bottom text) onto a canvas
setCopyStatus('Copying meme...')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix the disabled-state string mismatch.

Line 190 checks for 'Copying...', but Line 46 sets 'Copying meme...'. The button never disables, so users can start overlapping copy attempts.

Proposed fix
-          <button className="copy-button" onClick={handleCopyImageClick} disabled={copyStatus === 'Copying...'}>Copy image to clipboard</button>
+          <button className="copy-button" onClick={handleCopyImageClick} disabled={copyStatus === 'Copying meme...'}>Copy image to clipboard</button>

Also applies to: 190-190

🤖 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 `@components/Main.jsx` at line 46, The disabled-state string checked elsewhere
does not match the value set by setCopyStatus; update the code so the status
string is consistent: either change the call to setCopyStatus in the copy
handler to use 'Copying...' instead of 'Copying meme...' or change the
conditional that checks copy status (the comparison against 'Copying...') to
compare against 'Copying meme...'; locate the setCopyStatus call and the
button-disabled check to make both use the same exact string so the button
correctly disables during copy.

Comment thread components/Main.jsx
Comment on lines +143 to +155
if (navigator.clipboard && navigator.clipboard.writeText) {
await navigator.clipboard.writeText(memeInputs.imageUrl)
setCopyStatus('Could not copy combined meme (CORS). Image URL copied instead.')
} else {
const textarea = document.createElement('textarea')
textarea.value = memeInputs.imageUrl
document.body.appendChild(textarea)
textarea.select()
document.execCommand('copy')
document.body.removeChild(textarea)
setCopyStatus('Could not copy combined meme. Image URL copied (fallback).')
}
setTimeout(() => setCopyStatus(''), 5000)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

According to the current MDN docs, under what conditions can navigator.clipboard.writeText()reject, and what doesdocument.execCommand('copy') return when the copy operation is unsuccessful?

💡 Result:

According to MDN documentation, navigator.clipboard.writeText returns a Promise that is rejected if writing to the clipboard is not allowed [1]. While MDN generally states that the promise is rejected if clipboard access is denied [2], common conditions that lead to such rejections include failing to run the code in a secure context (HTTPS) [1][2], or failing to call the method within an appropriate user gesture event handler (such as pointerdown or pointerup) [3]. Regarding document.execCommand('copy'), MDN specifies that it returns a boolean value of false if the command is unsupported or disabled [4][5]. The documentation further notes that the method only returns true if it is invoked as part of a user interaction; it cannot be used to verify browser support before calling the command [4][5].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show relevant sections with line numbers
sed -n '1,260p' components/Main.jsx | nl -ba | sed -n '110,220p'

# Find all copyStatus usages to confirm disabled-state mismatch and accessibility
rg -n "copyStatus|setCopyStatus" components/Main.jsx

# Find where the copy button's disabled prop is set
rg -n "disabled\s*=" components/Main.jsx

# Find where the status message is rendered (look for copy status usage in JSX)
rg -n "copyStatus" components/Main.jsx

Repository: Devanshukoli/meme-generator

Length of output: 114


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Print range with line numbers using awk (nl not available)
awk 'NR>=110 && NR<=220 {printf "%4d\t%s\n", NR, $0}' components/Main.jsx

# Find all copyStatus / setCopyStatus usages
rg -n "copyStatus|setCopyStatus" components/Main.jsx

# Find where disabled prop is set for copy button
rg -n "disabled\s*=" components/Main.jsx

# Look for status rendering and aria-live
rg -n "aria-live|role=\"status\"|role='status'|status" components/Main.jsx

Repository: Devanshukoli/meme-generator

Length of output: 4676


Handle failures in the final URL-copy fallback

  • navigator.clipboard.writeText(memeInputs.imageUrl) can reject when clipboard access is denied/not allowed (e.g., insecure context, missing user gesture), and this branch has no try/catch—so a rejection can escape and leave the UI stuck in the prior copy state. Also check document.execCommand('copy')’s boolean return value and set an explicit failure status when it’s false.
  • The copy button disabled state is inconsistent: it disables only when copyStatus === 'Copying...', but the code sets setCopyStatus('Copying meme...'), so the button may not disable during copy.
  • The status message (<div className="copy-status">...) isn’t in a live region (aria-live/role="status"), so assistive tech may not announce updates.
🤖 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 `@components/Main.jsx` around lines 143 - 155, Wrap the
navigator.clipboard.writeText(memeInputs.imageUrl) call in a try/catch and on
rejection set an explicit failure message via setCopyStatus (e.g., "Could not
copy combined meme (clipboard denied). Image URL copied instead.") and continue
to the fallback; when using document.execCommand('copy') inspect its boolean
return value and set failure status if it returns false. Normalize the
copy-state strings so the button disable condition matches (either change
setCopyStatus to use 'Copying...' or change the button check to 'Copying
meme...') and ensure the timeout-clearing behavior remains. Finally, make the
status container (className "copy-status") an accessible live region (add
aria-live="polite" or role="status") so assistive tech announces updates.

Comment thread components/Main.jsx
</div>
<div className="copy-controls">
<button className="copy-button" onClick={handleCopyImageClick} disabled={copyStatus === 'Copying...'}>Copy image to clipboard</button>
{copyStatus && <div className="copy-status">{copyStatus}</div>}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Announce copy feedback to assistive tech.

The status text is visual-only right now. Adding a live region makes success and fallback messages audible to screen-reader users.

Proposed fix
-          {copyStatus && <div className="copy-status">{copyStatus}</div>}
+          {copyStatus && (
+            <div className="copy-status" role="status" aria-live="polite">
+              {copyStatus}
+            </div>
+          )}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{copyStatus && <div className="copy-status">{copyStatus}</div>}
{copyStatus && (
<div className="copy-status" role="status" aria-live="polite">
{copyStatus}
</div>
)}
🤖 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 `@components/Main.jsx` at line 191, The copy feedback div currently rendered by
Main.jsx using the copyStatus variable is visual-only; update the element that
renders {copyStatus} (the div with className "copy-status") to be an accessible
live region by adding appropriate attributes such as role="status" and
aria-live="polite" (and optionally aria-atomic="true") so screen readers will
announce success/fallback messages when copyStatus changes.

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.

1 participant