Various AT Protocol integrations with obsidian
at main 165 lines 4.4 kB view raw
1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>Atmosphere OAuth - Redirecting...</title> 7 <style> 8 * { 9 margin: 0; 10 padding: 0; 11 box-sizing: border-box; 12 } 13 body { 14 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; 15 display: flex; 16 align-items: center; 17 justify-content: center; 18 min-height: 100vh; 19 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 20 padding: 1rem; 21 } 22 .container { 23 text-align: center; 24 padding: 3rem 2rem; 25 background: white; 26 border-radius: 16px; 27 box-shadow: 0 20px 60px rgba(0,0,0,0.3); 28 max-width: 500px; 29 width: 100%; 30 } 31 h1 { 32 color: #667eea; 33 margin: 0 0 1rem 0; 34 font-size: 1.75rem; 35 font-weight: 600; 36 } 37 .spinner { 38 margin: 2rem auto; 39 width: 50px; 40 height: 50px; 41 border: 4px solid #f3f3f3; 42 border-top: 4px solid #667eea; 43 border-radius: 50%; 44 animation: spin 1s linear infinite; 45 } 46 @keyframes spin { 47 0% { transform: rotate(0deg); } 48 100% { transform: rotate(360deg); } 49 } 50 p { 51 color: #6b7280; 52 margin: 1rem 0; 53 line-height: 1.6; 54 } 55 .manual-link { 56 margin-top: 2rem; 57 padding: 1rem; 58 background: #f9fafb; 59 border-radius: 8px; 60 border: 1px solid #e5e7eb; 61 display: none; 62 } 63 .manual-link.show { 64 display: block; 65 } 66 .link-text { 67 word-break: break-all; 68 font-family: monospace; 69 font-size: 0.85rem; 70 color: #374151; 71 padding: 0.5rem; 72 background: white; 73 border-radius: 4px; 74 margin-top: 0.5rem; 75 } 76 button { 77 margin-top: 1rem; 78 padding: 0.75rem 1.5rem; 79 background: #667eea; 80 color: white; 81 border: none; 82 border-radius: 8px; 83 font-size: 1rem; 84 font-weight: 500; 85 cursor: pointer; 86 transition: background 0.2s; 87 } 88 button:hover { 89 background: #5568d3; 90 } 91 </style> 92</head> 93<body> 94 <div class="container"> 95 <h1>✅ Authentication Successful!</h1> 96 <div class="spinner"></div> 97 <p id="status">Redirecting to Obsidian...</p> 98 <div class="manual-link" id="manual-link"> 99 <p>If Obsidian doesn't open automatically:</p> 100 <p style="font-size: 0.9rem; margin-bottom: 0.5rem;">1. Copy the link below</p> 101 <div class="link-text" id="link-text"></div> 102 <button onclick="copyLink()">Copy Link</button> 103 <p style="font-size: 0.9rem; margin-top: 1rem;">2. Open Obsidian and paste it in your browser</p> 104 </div> 105 </div> 106 107 <script> 108 (function() { 109 try { 110 // extract OAuth parameters from URL hash (not search string) 111 const params = new URLSearchParams(window.location.hash.slice(1)); 112 113 const obsidianUri = `obsidian://atmosphere-oauth?${params.toString()}`; 114 115 // store the URI for manual copy 116 document.getElementById('link-text').textContent = obsidianUri; 117 118 window.location.href = obsidianUri; 119 120 setTimeout(function() { 121 const spinner = document.querySelector('.spinner'); 122 if (spinner) spinner.style.display = 'none'; 123 124 // Show success message 125 document.querySelector('h1').textContent = '✅ Redirected!'; 126 document.getElementById('status').textContent = 'Return to Obsidian to complete login.'; 127 128 setTimeout(function() { 129 try { 130 window.close(); 131 } catch (e) { 132 document.getElementById('status').textContent = 'You can close this window now.'; 133 } 134 }, 500); 135 }, 500); 136 137 // show manual instructions after a longer delay if still open 138 setTimeout(function() { 139 document.getElementById('manual-link').classList.add('show'); 140 }, 3000); 141 142 } catch (error) { 143 console.error('Redirect error:', error); 144 document.querySelector('.spinner').style.display = 'none'; 145 document.getElementById('status').textContent = 'An error occurred during redirect'; 146 document.getElementById('manual-link').classList.add('show'); 147 } 148 })(); 149 150 function copyLink() { 151 const linkText = document.getElementById('link-text').textContent; 152 navigator.clipboard.writeText(linkText).then(function() { 153 const btn = event.target; 154 btn.textContent = '✓ Copied!'; 155 setTimeout(function() { 156 btn.textContent = 'Copy Link'; 157 }, 2000); 158 }).catch(function(err) { 159 console.error('Failed to copy:', err); 160 alert('Failed to copy. Please select and copy the link manually.'); 161 }); 162 } 163 </script> 164</body> 165</html>