Skip to content

Commit f977075

Browse files
Merge pull request #675 from kavishkafernando/main
fix copy page site link issue
2 parents 7f20e49 + 11a830e commit f977075

1 file changed

Lines changed: 164 additions & 68 deletions

File tree

Lines changed: 164 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,47 @@
1-
import React, { useState, useRef, useEffect } from 'react';
2-
import styles from './styles.module.css';
1+
import React, { useState, useRef, useEffect } from "react";
2+
import styles from "./styles.module.css";
33

44
interface MarkdownButtonProps {
55
markdownUrl: string;
66
}
77

8-
export default function MarkdownButton({ markdownUrl }: MarkdownButtonProps): React.JSX.Element {
8+
export default function MarkdownButton({
9+
markdownUrl,
10+
}: MarkdownButtonProps): React.JSX.Element {
911
const [isOpen, setIsOpen] = useState(false);
1012
const [copied, setCopied] = useState(false);
1113
const dropdownRef = useRef<HTMLDivElement>(null);
1214

1315
// Close dropdown when clicking outside
1416
useEffect(() => {
1517
function handleClickOutside(event: MouseEvent) {
16-
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
18+
if (
19+
dropdownRef.current &&
20+
!dropdownRef.current.contains(event.target as Node)
21+
) {
1722
setIsOpen(false);
1823
}
1924
}
20-
document.addEventListener('mousedown', handleClickOutside);
21-
return () => document.removeEventListener('mousedown', handleClickOutside);
25+
document.addEventListener("mousedown", handleClickOutside);
26+
return () => document.removeEventListener("mousedown", handleClickOutside);
2227
}, []);
2328

2429
const handleCopyPage = async () => {
2530
try {
2631
const response = await fetch(markdownUrl);
27-
if (!response.ok) throw new Error('Failed to fetch');
32+
if (!response.ok) throw new Error("Failed to fetch");
2833
const markdown = await response.text();
2934
await navigator.clipboard.writeText(markdown);
3035
setCopied(true);
3136
setTimeout(() => setCopied(false), 2000);
3237
} catch (err) {
33-
console.error('Failed to copy:', err);
38+
console.error("Failed to copy:", err);
3439
}
3540
setIsOpen(false);
3641
};
3742

3843
const handleViewMarkdown = () => {
39-
window.open(markdownUrl, '_blank');
44+
window.open(markdownUrl, "_blank");
4045
setIsOpen(false);
4146
};
4247

@@ -59,18 +64,27 @@ export default function MarkdownButton({ markdownUrl }: MarkdownButtonProps): Re
5964
};
6065

6166
const handleOpenInClaude = () => {
62-
window.open(`https://claude.ai/new?q=${encodeURIComponent(getPromptWithMarkdown())}`, '_blank');
67+
window.open(
68+
`https://claude.ai/new?q=${encodeURIComponent(getPromptWithMarkdown())}`,
69+
"_blank",
70+
);
6371
setIsOpen(false);
6472
};
6573

6674
const handleOpenInChatGPT = () => {
6775
// ChatGPT has issues with .md URLs, so use HTML URL
68-
window.open(`https://chat.openai.com/?q=${encodeURIComponent(getPromptWithHtml())}`, '_blank');
76+
window.open(
77+
`https://chat.openai.com/?q=${encodeURIComponent(getPromptWithHtml())}`,
78+
"_blank",
79+
);
6980
setIsOpen(false);
7081
};
7182

7283
const handleOpenInPerplexity = () => {
73-
window.open(`https://www.perplexity.ai/?q=${encodeURIComponent(getPromptWithMarkdown())}`, '_blank');
84+
window.open(
85+
`https://www.perplexity.ai/?q=${encodeURIComponent(getPromptWithMarkdown())}`,
86+
"_blank",
87+
);
7488
setIsOpen(false);
7589
};
7690

@@ -82,61 +96,99 @@ export default function MarkdownButton({ markdownUrl }: MarkdownButtonProps): Re
8296
type="button"
8397
aria-expanded={isOpen}
8498
aria-haspopup="true"
99+
aria-label="Copy page URL"
85100
>
86101
<CopyIcon />
87-
<span>{copied ? 'Copied!' : 'Copy page'}</span>
102+
<span data-nosnippet>{copied ? "Copied!" : "Copy page"}</span>
88103
<ChevronIcon isOpen={isOpen} />
89104
</button>
90105

91106
{isOpen && (
92107
<>
93-
<div className={styles.mobileBackdrop} onClick={() => setIsOpen(false)} />
94-
<div className={styles.dropdownMenu}>
95-
<button className={styles.dropdownItem} onClick={handleCopyPage}>
96-
<CopyIcon />
97-
<div className={styles.dropdownItemText}>
98-
<span className={styles.dropdownItemTitle}>Copy page</span>
99-
<span className={styles.dropdownItemDesc}>Copy page as Markdown for LLMs</span>
100-
</div>
101-
</button>
102-
103-
<button className={styles.dropdownItem} onClick={handleViewMarkdown}>
104-
<MarkdownIcon />
105-
<div className={styles.dropdownItemText}>
106-
<span className={styles.dropdownItemTitle}>View as Markdown</span>
107-
<span className={styles.dropdownItemDesc}>View this page as plain text</span>
108-
</div>
109-
</button>
110-
111-
<div className={styles.dropdownDivider} />
112-
113-
<button className={styles.dropdownItem} onClick={handleOpenInChatGPT}>
114-
<ChatGPTIcon />
115-
<div className={styles.dropdownItemText}>
116-
<span className={styles.dropdownItemTitle}>Open in ChatGPT</span>
117-
<span className={styles.dropdownItemDesc}>Ask questions about this page</span>
118-
</div>
119-
<ExternalIcon />
120-
</button>
121-
122-
<button className={styles.dropdownItem} onClick={handleOpenInClaude}>
123-
<ClaudeIcon />
124-
<div className={styles.dropdownItemText}>
125-
<span className={styles.dropdownItemTitle}>Open in Claude</span>
126-
<span className={styles.dropdownItemDesc}>Ask questions about this page</span>
127-
</div>
128-
<ExternalIcon />
129-
</button>
130-
131-
<button className={styles.dropdownItem} onClick={handleOpenInPerplexity}>
132-
<PerplexityIcon />
133-
<div className={styles.dropdownItemText}>
134-
<span className={styles.dropdownItemTitle}>Open in Perplexity</span>
135-
<span className={styles.dropdownItemDesc}>Ask questions about this page</span>
136-
</div>
137-
<ExternalIcon />
138-
</button>
139-
</div>
108+
<div
109+
className={styles.mobileBackdrop}
110+
onClick={() => setIsOpen(false)}
111+
/>
112+
<div className={styles.dropdownMenu}>
113+
<button
114+
className={styles.dropdownItem}
115+
onClick={handleCopyPage}
116+
aria-label="Copy page URL"
117+
>
118+
<CopyIcon />
119+
<div className={styles.dropdownItemText}>
120+
<span className={styles.dropdownItemTitle} data-nosnippet>
121+
Copy page
122+
</span>
123+
<span className={styles.dropdownItemDesc}>
124+
Copy page as Markdown for LLMs
125+
</span>
126+
</div>
127+
</button>
128+
129+
<button
130+
className={styles.dropdownItem}
131+
onClick={handleViewMarkdown}
132+
>
133+
<MarkdownIcon />
134+
<div className={styles.dropdownItemText}>
135+
<span className={styles.dropdownItemTitle}>
136+
View as Markdown
137+
</span>
138+
<span className={styles.dropdownItemDesc}>
139+
View this page as plain text
140+
</span>
141+
</div>
142+
</button>
143+
144+
<div className={styles.dropdownDivider} />
145+
146+
<button
147+
className={styles.dropdownItem}
148+
onClick={handleOpenInChatGPT}
149+
>
150+
<ChatGPTIcon />
151+
<div className={styles.dropdownItemText}>
152+
<span className={styles.dropdownItemTitle}>
153+
Open in ChatGPT
154+
</span>
155+
<span className={styles.dropdownItemDesc}>
156+
Ask questions about this page
157+
</span>
158+
</div>
159+
<ExternalIcon />
160+
</button>
161+
162+
<button
163+
className={styles.dropdownItem}
164+
onClick={handleOpenInClaude}
165+
>
166+
<ClaudeIcon />
167+
<div className={styles.dropdownItemText}>
168+
<span className={styles.dropdownItemTitle}>Open in Claude</span>
169+
<span className={styles.dropdownItemDesc}>
170+
Ask questions about this page
171+
</span>
172+
</div>
173+
<ExternalIcon />
174+
</button>
175+
176+
<button
177+
className={styles.dropdownItem}
178+
onClick={handleOpenInPerplexity}
179+
>
180+
<PerplexityIcon />
181+
<div className={styles.dropdownItemText}>
182+
<span className={styles.dropdownItemTitle}>
183+
Open in Perplexity
184+
</span>
185+
<span className={styles.dropdownItemDesc}>
186+
Ask questions about this page
187+
</span>
188+
</div>
189+
<ExternalIcon />
190+
</button>
191+
</div>
140192
</>
141193
)}
142194
</div>
@@ -145,7 +197,13 @@ export default function MarkdownButton({ markdownUrl }: MarkdownButtonProps): Re
145197

146198
function CopyIcon() {
147199
return (
148-
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
200+
<svg
201+
width="16"
202+
height="16"
203+
viewBox="0 0 16 16"
204+
fill="currentColor"
205+
aria-hidden="true"
206+
>
149207
<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z" />
150208
<path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z" />
151209
</svg>
@@ -154,7 +212,13 @@ function CopyIcon() {
154212

155213
function MarkdownIcon() {
156214
return (
157-
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
215+
<svg
216+
width="16"
217+
height="16"
218+
viewBox="0 0 16 16"
219+
fill="currentColor"
220+
aria-hidden="true"
221+
>
158222
<path d="M14.85 3c.63 0 1.15.52 1.14 1.15v7.7c0 .63-.51 1.15-1.15 1.15H1.15C.52 13 0 12.48 0 11.84V4.15C0 3.52.52 3 1.15 3h13.7zM9 11V5H7l-1.5 2.25L4 5H2v6h2V8l1.5 2L7 8v3h2zm2.99.5L14.5 8H13V5h-2v3H9.5l2.49 3.5z" />
159223
</svg>
160224
);
@@ -168,7 +232,10 @@ function ChevronIcon({ isOpen }: { isOpen: boolean }) {
168232
viewBox="0 0 12 12"
169233
fill="currentColor"
170234
aria-hidden="true"
171-
style={{ transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)', transition: 'transform 0.2s' }}
235+
style={{
236+
transform: isOpen ? "rotate(180deg)" : "rotate(0deg)",
237+
transition: "transform 0.2s",
238+
}}
172239
>
173240
<path d="M2.22 4.47a.75.75 0 011.06 0L6 7.19l2.72-2.72a.75.75 0 111.06 1.06l-3.25 3.25a.75.75 0 01-1.06 0L2.22 5.53a.75.75 0 010-1.06z" />
174241
</svg>
@@ -177,7 +244,14 @@ function ChevronIcon({ isOpen }: { isOpen: boolean }) {
177244

178245
function ExternalIcon() {
179246
return (
180-
<svg width="12" height="12" viewBox="0 0 12 12" fill="currentColor" aria-hidden="true" className={styles.externalIcon}>
247+
<svg
248+
width="12"
249+
height="12"
250+
viewBox="0 0 12 12"
251+
fill="currentColor"
252+
aria-hidden="true"
253+
className={styles.externalIcon}
254+
>
181255
<path d="M3.5 3a.5.5 0 00-.5.5v5a.5.5 0 00.5.5h5a.5.5 0 00.5-.5V6.5a.5.5 0 011 0v2A1.5 1.5 0 018.5 10h-5A1.5 1.5 0 012 8.5v-5A1.5 1.5 0 013.5 2h2a.5.5 0 010 1h-2z" />
182256
<path d="M7 1.5a.5.5 0 01.5-.5h3a.5.5 0 01.5.5v3a.5.5 0 01-1 0V2.707L6.354 6.354a.5.5 0 11-.708-.708L9.293 2H7.5a.5.5 0 01-.5-.5z" />
183257
</svg>
@@ -186,24 +260,46 @@ function ExternalIcon() {
186260

187261
function ChatGPTIcon() {
188262
return (
189-
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
263+
<svg
264+
width="16"
265+
height="16"
266+
viewBox="0 0 24 24"
267+
fill="currentColor"
268+
aria-hidden="true"
269+
>
190270
<path d="M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.18a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .51 4.911 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.99 5.99 0 0 0 3.997-2.9 6.056 6.056 0 0 0-.747-7.073zM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.141-.081 4.779-2.758a.795.795 0 0 0 .392-.681v-6.737l2.02 1.168a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.494 4.494zM3.6 18.304a4.47 4.47 0 0 1-.535-3.014l.142.085 4.783 2.759a.771.771 0 0 0 .78 0l5.843-3.369v2.332a.08.08 0 0 1-.033.062L9.74 19.95a4.5 4.5 0 0 1-6.14-1.646zM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.676l5.815 3.355-2.02 1.168a.076.076 0 0 1-.071 0l-4.83-2.786A4.504 4.504 0 0 1 2.34 7.896zm16.597 3.855l-5.833-3.387L15.119 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.105v-5.678a.79.79 0 0 0-.407-.667zm2.01-3.023l-.141-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.5 4.5 0 0 1 6.68 4.66zm-12.64 4.135l-2.02-1.164a.08.08 0 0 1-.038-.057V6.075a4.5 4.5 0 0 1 7.375-3.453l-.142.08-4.778 2.758a.795.795 0 0 0-.393.681zm1.097-2.365l2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5z" />
191271
</svg>
192272
);
193273
}
194274

195275
function ClaudeIcon() {
196276
return (
197-
<svg width="16" height="16" viewBox="0 0 256 257" fill="currentColor" aria-hidden="true">
277+
<svg
278+
width="16"
279+
height="16"
280+
viewBox="0 0 256 257"
281+
fill="currentColor"
282+
aria-hidden="true"
283+
>
198284
<path d="m50.228 170.321 50.357-28.257.843-2.463-.843-1.361h-2.462l-8.426-.518-28.775-.778-24.952-1.037-24.175-1.296-6.092-1.297L0 125.796l.583-3.759 5.12-3.434 7.324.648 16.202 1.101 24.304 1.685 17.629 1.037 26.118 2.722h4.148l.583-1.685-1.426-1.037-1.101-1.037-25.147-17.045-27.22-18.017-14.258-10.37-7.713-5.25-3.888-4.925-1.685-10.758 7-7.713 9.397.649 2.398.648 9.527 7.323 20.35 15.75L94.817 91.9l3.889 3.24 1.555-1.102.195-.777-1.75-2.917-14.453-26.118-15.425-26.572-6.87-11.018-1.814-6.61c-.648-2.723-1.102-4.991-1.102-7.778l7.972-10.823L71.42 0 82.05 1.426l4.472 3.888 6.61 15.101 10.694 23.786 16.591 32.34 4.861 9.592 2.592 8.879.973 2.722h1.685v-1.556l1.36-18.211 2.528-22.36 2.463-28.776.843-8.1 4.018-9.722 7.971-5.25 6.222 2.981 5.12 7.324-.713 4.73-3.046 19.768-5.962 30.98-3.889 20.739h2.268l2.593-2.593 10.499-13.934 17.628-22.036 7.778-8.749 9.073-9.657 5.833-4.601h11.018l8.1 12.055-3.628 12.443-11.342 14.388-9.398 12.184-13.48 18.147-8.426 14.518.778 1.166 2.01-.194 30.46-6.481 16.462-2.982 19.637-3.37 8.88 4.148.971 4.213-3.5 8.62-20.998 5.184-24.628 4.926-36.682 8.685-.454.324.519.648 16.526 1.555 7.065.389h17.304l32.21 2.398 8.426 5.574 5.055 6.805-.843 5.184-12.962 6.611-17.498-4.148-40.83-9.721-14-3.5h-1.944v1.167l11.666 11.406 21.387 19.314 26.767 24.887 1.36 6.157-3.434 4.86-3.63-.518-23.526-17.693-9.073-7.972-20.545-17.304h-1.36v1.814l4.73 6.935 25.017 37.59 1.296 11.536-1.814 3.76-6.481 2.268-7.13-1.297-14.647-20.544-15.1-23.138-12.185-20.739-1.49.843-7.194 77.448-3.37 3.953-7.778 2.981-6.48-4.925-3.436-7.972 3.435-15.749 4.148-20.544 3.37-16.333 3.046-20.285 1.815-6.74-.13-.454-1.49.194-15.295 20.999-23.267 31.433-18.406 19.702-4.407 1.75-7.648-3.954.713-7.064 4.277-6.286 25.47-32.405 15.36-20.092 9.917-11.6-.065-1.686h-.583L44.07 198.125l-12.055 1.555-5.185-4.86.648-7.972 2.463-2.593 20.35-13.999-.064.065Z" />
199285
</svg>
200286
);
201287
}
202288

203289
function PerplexityIcon() {
204290
return (
205-
<svg width="16" height="16" viewBox="0 0 34 38" fill="currentColor" aria-hidden="true">
206-
<path fillRule="evenodd" clipRule="evenodd" d="M5.12114 0.0400391L15.919 9.98864V9.98636V0.062995H18.0209V10.0332L28.8671 0.0400391V11.3829H33.3202V27.744H28.8808V37.8442L18.0209 28.303V37.9538H15.919V28.4604L5.13338 37.96V27.744H0.680176V11.3829H5.12114V0.0400391ZM14.3344 13.4592H2.78208V25.6677H5.13074V21.8167L14.3344 13.4592ZM7.23518 22.7379V33.3271L15.919 25.6786V14.8506L7.23518 22.7379ZM18.0814 25.5775V14.8404L26.7677 22.7282V27.744H26.7789V33.219L18.0814 25.5775ZM28.8808 25.6677H31.2183V13.4592H19.752L28.8808 21.7302V25.6677ZM26.7652 11.3829V4.81584L19.6374 11.3829H26.7652ZM14.3507 11.3829H7.22306V4.81584L14.3507 11.3829Z" />
291+
<svg
292+
width="16"
293+
height="16"
294+
viewBox="0 0 34 38"
295+
fill="currentColor"
296+
aria-hidden="true"
297+
>
298+
<path
299+
fillRule="evenodd"
300+
clipRule="evenodd"
301+
d="M5.12114 0.0400391L15.919 9.98864V9.98636V0.062995H18.0209V10.0332L28.8671 0.0400391V11.3829H33.3202V27.744H28.8808V37.8442L18.0209 28.303V37.9538H15.919V28.4604L5.13338 37.96V27.744H0.680176V11.3829H5.12114V0.0400391ZM14.3344 13.4592H2.78208V25.6677H5.13074V21.8167L14.3344 13.4592ZM7.23518 22.7379V33.3271L15.919 25.6786V14.8506L7.23518 22.7379ZM18.0814 25.5775V14.8404L26.7677 22.7282V27.744H26.7789V33.219L18.0814 25.5775ZM28.8808 25.6677H31.2183V13.4592H19.752L28.8808 21.7302V25.6677ZM26.7652 11.3829V4.81584L19.6374 11.3829H26.7652ZM14.3507 11.3829H7.22306V4.81584L14.3507 11.3829Z"
302+
/>
207303
</svg>
208304
);
209305
}

0 commit comments

Comments
 (0)