Skip to content
33 changes: 25 additions & 8 deletions src/app/components/QRCode/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { PopiconsCopyLine } from "@popicons/react";
import { useTranslation } from "react-i18next";
import ReactQRCode from "react-qr-code";
import toast from "~/app/components/Toast";
import { classNames, useTheme } from "~/app/utils";

export type Props = {
Expand All @@ -21,15 +24,29 @@ export default function QRCode({ value, size, level, className }: Props) {
const theme = useTheme();
const fgColor = theme === "dark" ? "#FFFFFF" : "#000000";
const bgColor = theme === "dark" ? "#000000" : "#FFFFFF";
const { t } = useTranslation("common");

const handleCopy = () => {
navigator.clipboard.writeText(value);
toast.success(t("actions.copied_to_clipboard"));
};
Comment on lines +29 to +32
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling for clipboard API.

navigator.clipboard.writeText() returns a Promise that can reject (e.g., clipboard permission denied, insecure context). The current implementation ignores errors, which could result in silent failures with no user feedback.

🛡️ Proposed fix
  const handleCopy = () => {
-   navigator.clipboard.writeText(value);
-   toast.success(t("actions.copied_to_clipboard"));
+   navigator.clipboard.writeText(value)
+     .then(() => {
+       toast.success(t("actions.copied_to_clipboard"));
+     })
+     .catch((err) => {
+       console.error("Failed to copy:", err);
+       toast.error(t("actions.copy_failed"));
+     });
  };

Alternatively, using async/await:

- const handleCopy = () => {
-   navigator.clipboard.writeText(value);
-   toast.success(t("actions.copied_to_clipboard"));
+ const handleCopy = async () => {
+   try {
+     await navigator.clipboard.writeText(value);
+     toast.success(t("actions.copied_to_clipboard"));
+   } catch (err) {
+     if (err instanceof Error) {
+       toast.error(err.message);
+     }
+   }
  };

Note: You may need to add a translation key for the error case (e.g., actions.copy_failed).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/components/QRCode/index.tsx` around lines 29 - 32, The handleCopy
function currently calls navigator.clipboard.writeText(value) without awaiting
or handling rejection; change it to an async flow (or attach .then/.catch)
around navigator.clipboard.writeText in src/app/components/QRCode/index.tsx so
failures are caught and handled, and on success still call
toast.success(t("actions.copied_to_clipboard")), while on error call
toast.error(t("actions.copy_failed")) (or another translation key) and
optionally log the error; update the handleCopy implementation and ensure you
reference navigator.clipboard.writeText, handleCopy, toast.success/toast.error,
and t(...) in the fix.


return (
<ReactQRCode
value={value}
size={size}
fgColor={fgColor}
bgColor={bgColor}
className={classNames("w-full h-auto rounded-md", className ?? "")}
level={level}
/>
<div className="relative cursor-pointer group" onClick={handleCopy}>
<ReactQRCode
value={value}
size={size}
fgColor={fgColor}
bgColor={bgColor}
className={classNames(
"w-full h-auto rounded-md transition-opacity group-hover:opacity-80",
className ?? ""
)}
level={level}
/>
<div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity">
<PopiconsCopyLine className="h-8 w-8 text-white drop-shadow-lg" />
Copy link
Contributor

Choose a reason for hiding this comment

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

where this is used now? i don't see any apperance of this

</div>
Comment on lines +47 to +49
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Copy icon is invisible on light theme.

The copy icon uses text-white which won't be visible against the white QR code background (bgColor is #FFFFFF on light theme). Even with the QR opacity reduced to 80% on hover, a white icon on a near-white background lacks sufficient contrast.

Consider using a theme-aware color or adding a semi-transparent background behind the icon.

🎨 Proposed fix - add background to icon container
      <div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity">
-       <PopiconsCopyLine className="h-8 w-8 text-white drop-shadow-lg" />
+       <div className="bg-black/50 dark:bg-white/50 rounded-full p-2">
+         <PopiconsCopyLine className="h-8 w-8 text-white dark:text-black drop-shadow-lg" />
+       </div>
      </div>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/components/QRCode/index.tsx` around lines 47 - 49, The copy icon is
invisible on light backgrounds; update the icon container (the div wrapping
PopiconsCopyLine in the QRCode component) to add a semi-transparent circular
background and make the icon theme-aware—e.g. add classes like "rounded-full p-1
bg-black/50 dark:bg-white/50" to the container and change the icon class from
"text-white" to a theme-aware class such as "text-white dark:text-black" (or
equivalent tailwind dark/light variants) so the icon remains visible on both
light and dark QR backgrounds.

</div>
);
}
2 changes: 1 addition & 1 deletion src/app/screens/ReceiveInvoice/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ function ReceiveInvoice() {
<div className="relative flex items-center justify-center">
<QRCode
value={invoice.paymentRequest.toUpperCase()}
size={512}
size={192}
Copy link
Contributor

Choose a reason for hiding this comment

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

revert

/>
{isAlbyOAuthUser ? (
<>
Expand Down