A human-friendly DSL for ATProto Lexicons
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add share button

+97
+25
website/sass/style.scss
··· 422 422 border-color: var(--accent); 423 423 } 424 424 425 + .share-btn { 426 + padding: 0.375rem 1rem; 427 + background: var(--accent); 428 + color: white; 429 + border: none; 430 + border-radius: 0.25rem; 431 + font-size: 0.875rem; 432 + font-weight: 500; 433 + cursor: pointer; 434 + transition: background 0.2s, transform 0.1s; 435 + } 436 + 437 + .share-btn:hover { 438 + background: var(--accent-hover); 439 + transform: translateY(-1px); 440 + } 441 + 442 + .share-btn:active { 443 + transform: translateY(0); 444 + } 445 + 446 + .share-btn.copied { 447 + background: #10b981; 448 + } 449 + 425 450 .tabs { 426 451 display: flex; 427 452 gap: 0.5rem;
+71
website/static/js/app.js
··· 131 131 initEditor(); 132 132 setupEventListeners(); 133 133 134 + // Load from URL if share parameter exists 135 + loadFromUrl(); 136 + 134 137 // Generate initial output 135 138 handleCheck(); 136 139 } catch (error) { ··· 419 422 timeout = setTimeout(handleCheck, 500); 420 423 }); 421 424 } 425 + 426 + // Share button 427 + const shareBtn = document.getElementById('share-btn'); 428 + if (shareBtn) { 429 + shareBtn.addEventListener('click', handleShare); 430 + } 422 431 } 423 432 424 433 function switchTab(tabName) { ··· 545 554 resultDiv.textContent = message; 546 555 resultDiv.className = 'error'; 547 556 resultDiv.style.display = 'block'; 557 + } 558 + 559 + // Base64url encoding (URL-safe base64) 560 + function base64urlEncode(str) { 561 + // Convert string to base64 562 + const base64 = btoa(unescape(encodeURIComponent(str))); 563 + // Make it URL-safe by replacing +/= with -_~ 564 + return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '~'); 565 + } 566 + 567 + function base64urlDecode(str) { 568 + // Convert URL-safe base64 back to regular base64 569 + const base64 = str.replace(/-/g, '+').replace(/_/g, '/').replace(/~/g, '='); 570 + // Decode base64 to string 571 + return decodeURIComponent(escape(atob(base64))); 572 + } 573 + 574 + function loadFromUrl() { 575 + const urlParams = new URLSearchParams(window.location.search); 576 + const shareParam = urlParams.get('share'); 577 + 578 + if (shareParam) { 579 + try { 580 + const decoded = base64urlDecode(shareParam); 581 + const textarea = document.getElementById('mlf-editor'); 582 + if (textarea) { 583 + textarea.value = decoded; 584 + updateLineNumbers(decoded); 585 + updateHighlighting(decoded); 586 + } 587 + } catch (error) { 588 + console.error('Failed to load shared code:', error); 589 + showError('Failed to load shared code. The link may be corrupted.'); 590 + } 591 + } 592 + } 593 + 594 + function handleShare() { 595 + const source = getEditorContent(); 596 + const encoded = base64urlEncode(source); 597 + 598 + // Build share URL 599 + const baseUrl = window.location.origin + window.location.pathname; 600 + const shareUrl = `${baseUrl}?share=${encoded}`; 601 + 602 + // Copy to clipboard 603 + navigator.clipboard.writeText(shareUrl).then(() => { 604 + // Show success feedback 605 + const shareBtn = document.getElementById('share-btn'); 606 + const originalText = shareBtn.textContent; 607 + shareBtn.textContent = 'Copied!'; 608 + shareBtn.classList.add('copied'); 609 + 610 + setTimeout(() => { 611 + shareBtn.textContent = originalText; 612 + shareBtn.classList.remove('copied'); 613 + }, 2000); 614 + }).catch(err => { 615 + console.error('Failed to copy to clipboard:', err); 616 + // Fallback: show the URL in a prompt 617 + prompt('Copy this URL to share:', shareUrl); 618 + }); 548 619 } 549 620 550 621 // Initialize when DOM is ready
+1
website/templates/playground.html
··· 8 8 <div class="file-path-container"> 9 9 <input type="text" id="file-path" value="com/example/forum/thread.mlf" spellcheck="false" /> 10 10 </div> 11 + <button id="share-btn" class="share-btn" title="Share this code">Share</button> 11 12 </div> 12 13 <textarea id="mlf-editor" spellcheck="false">/// A forum thread 13 14 record thread {