Skip to content

Commit 451f2cf

Browse files
Jon DahlJon Dahl
authored andcommitted
add copy button to metadata
1 parent f924808 commit 451f2cf

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

components/player-page.tsx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,15 @@ const PlayerPage: React.FC<PageProps> = ({ playbackId, videoExists, shareUrl, po
3535
const [showMetadata, setShowMetadata] = useState(false);
3636
const [metadataLoading, setMetadataLoading] = useState(false);
3737
const [metadata, setMetadata] = useState<any>(null);
38+
const [isMetadataCopied, setIsMetadataCopied] = useState(false);
3839
const copyTimeoutRef = useRef<number | null>(null);
40+
const metadataCopyTimeoutRef = useRef<number | null>(null);
3941
const router = useRouter();
4042

4143
useEffect(() => {
4244
return () => {
4345
if (copyTimeoutRef.current) clearTimeout(copyTimeoutRef.current);
46+
if (metadataCopyTimeoutRef.current) clearTimeout(metadataCopyTimeoutRef.current);
4447
};
4548
}, []);
4649

@@ -201,6 +204,17 @@ const PlayerPage: React.FC<PageProps> = ({ playbackId, videoExists, shareUrl, po
201204
}
202205
};
203206

207+
const copyMetadata = () => {
208+
if (metadata) {
209+
copy(JSON.stringify(metadata, null, 2));
210+
setIsMetadataCopied(true);
211+
metadataCopyTimeoutRef.current = window.setTimeout(() => {
212+
setIsMetadataCopied(false);
213+
metadataCopyTimeoutRef.current = null;
214+
}, 2000);
215+
}
216+
};
217+
204218
if (errorMessage) {
205219
return (
206220
<Layout darkMode >
@@ -326,6 +340,35 @@ const PlayerPage: React.FC<PageProps> = ({ playbackId, videoExists, shareUrl, po
326340
>
327341
{showMetadata ? 'Hide Metadata' : 'Show Metadata'}
328342
</a>
343+
{showMetadata && metadata && (
344+
<a
345+
onClick={copyMetadata}
346+
onKeyPress={copyMetadata}
347+
role="button"
348+
tabIndex={0}
349+
className="copy-metadata-link"
350+
title="Copy"
351+
>
352+
<svg
353+
width="16"
354+
height="16"
355+
viewBox="0 0 16 16"
356+
fill="none"
357+
xmlns="http://www.w3.org/2000/svg"
358+
className="copy-icon"
359+
>
360+
<path
361+
d="M10.5 1.5H3.5C2.67157 1.5 2 2.17157 2 3V11H3.5V3H10.5V1.5Z"
362+
fill="currentColor"
363+
/>
364+
<path
365+
d="M12.5 4.5H6.5C5.67157 4.5 5 5.17157 5 6V13C5 13.8284 5.67157 14.5 6.5 14.5H12.5C13.3284 14.5 14 13.8284 14 13V6C14 5.17157 13.3284 4.5 12.5 4.5ZM12.5 13H6.5V6H12.5V13Z"
366+
fill="currentColor"
367+
/>
368+
</svg>
369+
{isMetadataCopied && <span className="copy-success">Copied!</span>}
370+
</a>
371+
)}
329372
</div>
330373
{showMetadata && (
331374
<div className="metadata-panel">
@@ -397,6 +440,9 @@ const PlayerPage: React.FC<PageProps> = ({ playbackId, videoExists, shareUrl, po
397440
margin-top: 15px;
398441
padding-top: 15px;
399442
border-top: 1px solid rgba(255, 255, 255, 0.1);
443+
display: flex;
444+
justify-content: space-between;
445+
align-items: center;
400446
}
401447
.metadata-link {
402448
color: #ccc;
@@ -412,6 +458,29 @@ const PlayerPage: React.FC<PageProps> = ({ playbackId, videoExists, shareUrl, po
412458
padding-top: 15px;
413459
border-top: 1px solid rgba(255, 255, 255, 0.1);
414460
}
461+
.copy-metadata-link {
462+
display: inline-flex;
463+
align-items: center;
464+
gap: 8px;
465+
color: #ccc;
466+
cursor: pointer;
467+
padding: 4px 8px;
468+
border-radius: 4px;
469+
transition: all 0.2s ease;
470+
}
471+
.copy-metadata-link:hover {
472+
color: #fff;
473+
background: rgba(255, 255, 255, 0.1);
474+
}
475+
.copy-icon {
476+
width: 16px;
477+
height: 16px;
478+
flex-shrink: 0;
479+
}
480+
.copy-success {
481+
font-size: 12px;
482+
color: #4ade80;
483+
}
415484
.metadata-loading {
416485
color: #ccc;
417486
font-style: italic;

0 commit comments

Comments
 (0)