Skip to content

Commit

Permalink
fix: apply coderabbitai suggestions
Browse files Browse the repository at this point in the history
- add browser compatibility check for Clipboard API
- propagate copy to clipboard error for higher-level handling
- add error handling and improve user feedback to ratelimits logs menu
  • Loading branch information
unrenamed committed Nov 13, 2024
1 parent c385257 commit 26055c5
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 17 deletions.
16 changes: 11 additions & 5 deletions apps/dashboard/app/(app)/ratelimits/[namespaceId]/logs/menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,17 @@ export const Menu: React.FC<Props> = ({ namespace, identifier }) => {
<DropdownMenuContent className="w-56">
<DropdownMenuItem
onClick={() => {
copyToClipboard(identifier).then(() =>
toast.success("Copied to clipboard", {
description: identifier,
}),
);
copyToClipboard(identifier)
.then(() =>
toast.success("Identifier copied to clipboard", {
description: identifier,
}),
)
.catch((err) =>
toast.error("Failed to copy to clipboard", {
description: (err as Error).message,
}),
);
}}
>
<Copy className="w-4 h-4 mr-2" />
Expand Down
43 changes: 31 additions & 12 deletions internal/ui/src/hooks/use-copy-to-clipboard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useCallback, useEffect, useRef, useState } from "react";

const DEFAULT_TIMEOUT = 3000;

export const useCopyToClipboard = (
timeout = 3000,
timeout = DEFAULT_TIMEOUT,
): [boolean, (value: string | ClipboardItem) => Promise<void>] => {
const timer = useRef<ReturnType<typeof setTimeout> | null>(null);
const [copied, setCopied] = useState(false);
Expand All @@ -13,23 +15,40 @@ export const useCopyToClipboard = (
}
};

const writeToClipboard = async (value: string | ClipboardItem) => {
const isClipboardAvailable =
typeof navigator !== "undefined" && navigator.clipboard !== undefined;

if (!isClipboardAvailable) {
throw new Error("Clipboard API is not supported in this browser");
}

if (typeof value === "string") {
await navigator.clipboard.writeText(value);
} else if (value instanceof ClipboardItem) {
await navigator.clipboard.write([value]);
}
};

const handleTimeout = () => {
if (Number.isFinite(timeout) && timeout >= 0) {
timer.current = setTimeout(() => setCopied(false), timeout);
} else {
console.warn(`Invalid timeout value; defaulting to ${DEFAULT_TIMEOUT}ms`);
timer.current = setTimeout(() => setCopied(false), DEFAULT_TIMEOUT);
}
};

const copyToClipboard = useCallback(
async (value: string | ClipboardItem) => {
clearTimer();
try {
if (typeof value === "string") {
await navigator.clipboard.writeText(value);
} else if (value instanceof ClipboardItem) {
await navigator.clipboard.write([value]);
}
await writeToClipboard(value);
setCopied(true);

// Ensure timeout is a non-negative finite number
if (Number.isFinite(timeout) && timeout >= 0) {
timer.current = setTimeout(() => setCopied(false), timeout);
}
handleTimeout();
} catch (error) {
console.error("Failed to copy: ", error);
console.warn("Failed to copy to clipboard. ", error);
throw error; // Propagate error for higher-level handling
}
},
[timeout],
Expand Down

0 comments on commit 26055c5

Please sign in to comment.