|
409 | 409 | }); |
410 | 410 | } |
411 | 411 |
|
| 412 | + function copyShareableLink() { |
| 413 | + const selected = getSelectedModels(); |
| 414 | + if (selected.length === 0) { |
| 415 | + alert('Please select at least one model to share.'); |
| 416 | + return; |
| 417 | + } |
| 418 | + |
| 419 | + const chartType = document.getElementById('compare-chart-type'); |
| 420 | + const chartTypeValue = chartType ? chartType.value : 'bar'; |
| 421 | + |
| 422 | + // Get current leaderboard |
| 423 | + const container = document.getElementById('leaderboard-container'); |
| 424 | + const active = container ? container.querySelector('.tabcontent.active') : null; |
| 425 | + const leaderboardId = active ? active.id.replace('leaderboard-', '') : 'verified'; |
| 426 | + |
| 427 | + // Build URL parameters |
| 428 | + const params = new URLSearchParams(); |
| 429 | + params.set('leaderboard', leaderboardId); |
| 430 | + params.set('chart', chartTypeValue); |
| 431 | + params.set('models', selected.map(m => m.name).join(',')); |
| 432 | + |
| 433 | + // Create full URL |
| 434 | + const baseUrl = window.location.origin + window.location.pathname; |
| 435 | + const shareUrl = `${baseUrl}?${params.toString()}`; |
| 436 | + |
| 437 | + // Copy to clipboard |
| 438 | + if (navigator.clipboard && navigator.clipboard.writeText) { |
| 439 | + navigator.clipboard.writeText(shareUrl).then(() => { |
| 440 | + // Visual feedback |
| 441 | + const btn = document.getElementById('copy-link-btn'); |
| 442 | + if (btn) { |
| 443 | + const originalHTML = btn.innerHTML; |
| 444 | + btn.innerHTML = '<i class="fa fa-check"></i> Copied!'; |
| 445 | + btn.classList.add('btn-success'); |
| 446 | + btn.classList.remove('btn-outline-secondary'); |
| 447 | + setTimeout(() => { |
| 448 | + btn.innerHTML = originalHTML; |
| 449 | + btn.classList.remove('btn-success'); |
| 450 | + btn.classList.add('btn-outline-secondary'); |
| 451 | + }, 2000); |
| 452 | + } |
| 453 | + }).catch(err => { |
| 454 | + console.error('Failed to copy link:', err); |
| 455 | + alert('Failed to copy link to clipboard. Please copy manually:\n' + shareUrl); |
| 456 | + }); |
| 457 | + } else { |
| 458 | + // Fallback for older browsers |
| 459 | + alert('Copy this link:\n' + shareUrl); |
| 460 | + } |
| 461 | + } |
| 462 | + |
| 463 | + function restoreStateFromURL() { |
| 464 | + const params = new URLSearchParams(window.location.search); |
| 465 | + |
| 466 | + if (!params.has('models')) { |
| 467 | + return; // No state to restore |
| 468 | + } |
| 469 | + |
| 470 | + const leaderboardName = params.get('leaderboard') || 'verified'; |
| 471 | + const chartType = params.get('chart') || 'bar'; |
| 472 | + const modelNames = params.get('models').split(',').filter(m => m.trim()); |
| 473 | + |
| 474 | + if (modelNames.length === 0) { |
| 475 | + return; |
| 476 | + } |
| 477 | + |
| 478 | + // Switch to the correct leaderboard tab |
| 479 | + const leaderboardTab = document.querySelector(`[data-leaderboard="${leaderboardName}"]`); |
| 480 | + if (leaderboardTab) { |
| 481 | + leaderboardTab.click(); |
| 482 | + } |
| 483 | + |
| 484 | + // Wait a bit for the tab to load, then select models |
| 485 | + setTimeout(() => { |
| 486 | + const container = document.getElementById('leaderboard-container'); |
| 487 | + const active = container ? container.querySelector('.tabcontent.active') : null; |
| 488 | + if (!active) return; |
| 489 | + |
| 490 | + // Deselect all first |
| 491 | + const allCheckboxes = active.querySelectorAll('input.row-select'); |
| 492 | + allCheckboxes.forEach(cb => cb.checked = false); |
| 493 | + |
| 494 | + // Select the models from URL |
| 495 | + modelNames.forEach(modelName => { |
| 496 | + const checkbox = active.querySelector(`input.row-select[data-model="${modelName}"]`); |
| 497 | + if (checkbox) { |
| 498 | + checkbox.checked = true; |
| 499 | + } |
| 500 | + }); |
| 501 | + |
| 502 | + // Open the compare modal |
| 503 | + openModal(); |
| 504 | + |
| 505 | + // Set the chart type |
| 506 | + const chartTypeSelect = document.getElementById('compare-chart-type'); |
| 507 | + if (chartTypeSelect) { |
| 508 | + chartTypeSelect.value = chartType; |
| 509 | + } |
| 510 | + |
| 511 | + // Render the chart |
| 512 | + renderChart(); |
| 513 | + }, 300); |
| 514 | + } |
| 515 | + |
412 | 516 | function initEvents() { |
413 | 517 | // Listen for global theme changes (e.g., from sidebar toggle) |
414 | 518 | const observer = new MutationObserver((mutations) => { |
|
509 | 613 | }); |
510 | 614 | } |
511 | 615 |
|
| 616 | + // Copy link button handler |
| 617 | + const copyLinkBtn = document.getElementById('copy-link-btn'); |
| 618 | + if (copyLinkBtn) { |
| 619 | + copyLinkBtn.addEventListener('click', (e) => { |
| 620 | + e.preventDefault(); |
| 621 | + copyShareableLink(); |
| 622 | + }); |
| 623 | + } |
| 624 | + |
512 | 625 | // No selection modal close handlers |
513 | 626 | const noSelectionModal = document.getElementById('no-selection-modal'); |
514 | 627 | if (noSelectionModal) { |
|
549 | 662 | } |
550 | 663 | } |
551 | 664 | }); |
| 665 | + |
| 666 | + // Restore state from URL if present |
| 667 | + restoreStateFromURL(); |
552 | 668 | } |
553 | 669 |
|
554 | 670 | if (document.readyState === 'loading') { |
|
0 commit comments