|
255 | 255 | !download.title && |
256 | 256 | ['PENDING', 'FETCHING_INFO', 'DOWNLOADING'].includes(download.status) |
257 | 257 | ); |
| 258 | +
|
| 259 | + let urlCopied = $state(false); |
| 260 | + async function copySourceUrl() { |
| 261 | + await navigator.clipboard.writeText(download.url); |
| 262 | + urlCopied = true; |
| 263 | + setTimeout(() => (urlCopied = false), 1500); |
| 264 | + } |
258 | 265 | </script> |
259 | 266 |
|
260 | 267 | <svelte:head> |
|
508 | 515 |
|
509 | 516 | <div class="source-url"> |
510 | 517 | <span class="meta-label">Source</span> |
511 | | - <a href={download.url} target="_blank" rel="noopener noreferrer" class="url-link">{download.url}</a> |
| 518 | + <div class="url-row"> |
| 519 | + <a href={download.url} target="_blank" rel="noopener noreferrer" class="url-link">{download.url}</a> |
| 520 | + <button |
| 521 | + class="copy-url-btn" |
| 522 | + class:copied={urlCopied} |
| 523 | + onclick={copySourceUrl} |
| 524 | + title={urlCopied ? 'Copied!' : 'Copy source URL'} |
| 525 | + > |
| 526 | + {#if urlCopied} |
| 527 | + <svg viewBox="0 0 20 20" fill="currentColor" width="14" height="14"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" /></svg> |
| 528 | + {:else} |
| 529 | + <svg viewBox="0 0 20 20" fill="currentColor" width="14" height="14"><path fill-rule="evenodd" d="M4.25 5.5a.75.75 0 00-.75.75v8.5c0 .414.336.75.75.75h8.5a.75.75 0 00.75-.75v-4a.75.75 0 011.5 0v4A2.25 2.25 0 0112.75 17h-8.5A2.25 2.25 0 012 14.75v-8.5A2.25 2.25 0 014.25 4h5a.75.75 0 010 1.5h-5zm4.03-.78a.75.75 0 011.06 0L15 10.38V7.75a.75.75 0 011.5 0v4.5a.75.75 0 01-.75.75h-4.5a.75.75 0 010-1.5h2.63L8.28 5.78a.75.75 0 010-1.06z" clip-rule="evenodd" /></svg> |
| 530 | + {/if} |
| 531 | + </button> |
| 532 | + </div> |
512 | 533 | </div> |
513 | 534 | </div> |
514 | 535 | </div> |
|
899 | 920 | gap: 4px; |
900 | 921 | } |
901 | 922 |
|
| 923 | + .url-row { |
| 924 | + display: flex; |
| 925 | + align-items: flex-start; |
| 926 | + gap: var(--spacing-xs); |
| 927 | + } |
| 928 | +
|
902 | 929 | .url-link { |
903 | 930 | font-size: 0.8125rem; |
904 | 931 | color: var(--color-accent-primary); |
|
910 | 937 | text-decoration: underline; |
911 | 938 | } |
912 | 939 |
|
| 940 | + .copy-url-btn { |
| 941 | + display: flex; |
| 942 | + align-items: center; |
| 943 | + justify-content: center; |
| 944 | + background: none; |
| 945 | + border: none; |
| 946 | + color: var(--color-text-tertiary); |
| 947 | + cursor: pointer; |
| 948 | + padding: 2px; |
| 949 | + border-radius: var(--radius-sm); |
| 950 | + transition: all var(--transition-fast); |
| 951 | + flex-shrink: 0; |
| 952 | + margin-top: 1px; |
| 953 | + } |
| 954 | +
|
| 955 | + .copy-url-btn:hover { |
| 956 | + color: var(--color-accent-primary); |
| 957 | + background: var(--color-bg-tertiary); |
| 958 | + } |
| 959 | +
|
| 960 | + .copy-url-btn.copied { |
| 961 | + color: var(--color-status-success); |
| 962 | + } |
| 963 | +
|
913 | 964 | .similar-section { |
914 | 965 | margin-top: var(--spacing-2xl); |
915 | 966 | padding-top: var(--spacing-xl); |
|
0 commit comments