ATlast — you'll never need to find your favorites on another platform again. Find your favs in the ATmosphere.
atproto
16
fork

Configure Feed

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

chores: auto-lint html, move env stuff to fix mock mode

byarielm.fyi f2718d8f 9224f892

verified
+128 -30
.env.example packages/web/.env.example
+4
.gitignore
··· 1 1 .env 2 + .env.mock 2 3 .tangled/ 4 + .github/ 3 5 .vscode/ 4 6 .netlify/ 5 7 .claude/ 6 8 .deciduous/ 7 9 node_modules/ 10 + docs/ 8 11 dist/ 9 12 private-key.pem 10 13 public-jwk.json 11 14 test-data/ 12 15 PLAN.md 16 + CLAUDE.md
+124 -30
packages/extension/src/popup/popup.html
··· 6 6 <title>ATlast Importer</title> 7 7 <link rel="stylesheet" href="popup.css" /> 8 8 </head> 9 - <body class="w-[350px] min-h-[400px] font-sans text-slate-800 dark:text-cyan-50 bg-gradient-to-br from-purple-50 via-white to-cyan-50 dark:from-slate-900 dark:via-purple-950 dark:to-sky-900"> 9 + <body 10 + class="w-[350px] min-h-[400px] font-sans bg-gradient-to-br from-cyan-50 via-purple-50 to-pink-50 dark:from-indigo-950 dark:via-purple-900 dark:to-slate-900 text-slate-900 dark:text-slate-100 transition-colors duration-300 text-1xl font-bold mb-2 text-center" 11 + > 10 12 <div class="flex flex-col min-h-[400px]"> 11 13 <header class="bg-firefly-banner text-white p-5 text-center"> 12 14 <h1 class="text-xl font-bold mb-1">ATlast Importer</h1> 13 - <p class="text-[13px] opacity-90">Find your follows in the ATmosphere</p> 15 + <p class="text-[13px] opacity-90"> 16 + Find your follows in the ATmosphere 17 + </p> 14 18 </header> 15 19 16 - <main id="app" class="flex-1 px-5 py-6 flex items-center justify-center"> 20 + <main 21 + id="app" 22 + class="flex-1 px-5 py-6 flex items-center justify-center" 23 + > 17 24 <!-- Idle state --> 18 25 <div id="state-idle" class="w-full text-center hidden"> 19 26 <div class="text-5xl mb-4">🔍</div> 20 - <p class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50"> 27 + <p 28 + class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50" 29 + > 21 30 Go to your Twitter/X Following page to start 22 31 </p> 23 - <p class="text-[13px] text-slate-500 dark:text-slate-400 mt-2">Visit x.com/yourusername/following</p> 32 + <p 33 + class="text-[13px] text-slate-500 dark:text-slate-400 mt-2" 34 + > 35 + Visit x.com/yourusername/following 36 + </p> 24 37 </div> 25 38 26 39 <!-- Ready state --> 27 40 <div id="state-ready" class="w-full text-center hidden"> 28 41 <div class="text-5xl mb-4">✅</div> 29 - <p class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50"> 42 + <p 43 + class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50" 44 + > 30 45 Ready to scan <span id="platform-name"></span> 31 46 </p> 32 - <button id="btn-start" class="w-full bg-orange-600 hover:bg-orange-700 text-white font-semibold py-3 px-6 rounded-lg mt-4 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-lg hover:shadow-orange-600/30 active:translate-y-0"> 47 + <button 48 + id="btn-start" 49 + class="w-full bg-orange-600 hover:bg-orange-700 text-white font-semibold py-3 px-6 rounded-lg mt-4 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-lg hover:shadow-orange-600/30 active:translate-y-0" 50 + > 33 51 Start Scan 34 52 </button> 35 53 </div> ··· 37 55 <!-- Scraping state --> 38 56 <div id="state-scraping" class="w-full text-center hidden"> 39 57 <div class="text-5xl mb-4 spinner">⏳</div> 40 - <p class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50">Scanning...</p> 58 + <p 59 + class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50" 60 + > 61 + Scanning... 62 + </p> 41 63 <div class="mt-5"> 42 - <div class="w-full h-2 bg-sky-50 dark:bg-slate-800 rounded overflow-hidden mb-3"> 43 - <div id="progress-fill" class="h-full bg-gradient-to-r from-orange-600 to-pink-600 w-0 transition-all duration-300 progress-fill"></div> 64 + <div 65 + class="w-full h-2 bg-sky-50 dark:bg-slate-800 rounded overflow-hidden mb-3" 66 + > 67 + <div 68 + id="progress-fill" 69 + class="h-full bg-gradient-to-r from-orange-600 to-pink-600 w-0 transition-all duration-300 progress-fill" 70 + ></div> 44 71 </div> 45 - <p class="text-base font-semibold text-slate-700 dark:text-cyan-50"> 72 + <p 73 + class="text-base font-semibold text-slate-700 dark:text-cyan-50" 74 + > 46 75 Found <span id="count">0</span> users 47 76 </p> 48 - <p id="status-message" class="text-[13px] text-slate-500 dark:text-slate-400 mt-2"></p> 77 + <p 78 + id="status-message" 79 + class="text-[13px] text-slate-500 dark:text-slate-400 mt-2" 80 + ></p> 49 81 </div> 50 82 </div> 51 83 52 84 <!-- Complete state --> 53 85 <div id="state-complete" class="w-full text-center hidden"> 54 86 <div class="text-5xl mb-4">🎉</div> 55 - <p class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50">Scan complete!</p> 87 + <p 88 + class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50" 89 + > 90 + Scan complete! 91 + </p> 56 92 <p class="text-sm text-slate-500 dark:text-slate-400 mt-2"> 57 - Found <strong id="final-count" class="text-orange-600 dark:text-orange-400 text-lg">0</strong> users 93 + Found 94 + <strong 95 + id="final-count" 96 + class="text-orange-600 dark:text-orange-400 text-lg" 97 + >0</strong 98 + > 99 + users 58 100 </p> 59 - <button id="btn-upload" class="w-full bg-orange-600 hover:bg-orange-700 text-white font-semibold py-3 px-6 rounded-lg mt-4 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-lg hover:shadow-orange-600/30 active:translate-y-0"> 101 + <button 102 + id="btn-upload" 103 + class="w-full bg-orange-600 hover:bg-orange-700 text-white font-semibold py-3 px-6 rounded-lg mt-4 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-lg hover:shadow-orange-600/30 active:translate-y-0" 104 + > 60 105 Open in ATlast 61 106 </button> 62 107 </div> ··· 64 109 <!-- Uploading state --> 65 110 <div id="state-uploading" class="w-full text-center hidden"> 66 111 <div class="text-5xl mb-4 spinner">📤</div> 67 - <p class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50">Uploading to ATlast...</p> 112 + <p 113 + class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50" 114 + > 115 + Uploading to ATlast... 116 + </p> 68 117 </div> 69 118 70 119 <!-- Error state --> 71 120 <div id="state-error" class="w-full text-center hidden"> 72 121 <div class="text-5xl mb-4">⚠️</div> 73 - <p class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50">Error</p> 74 - <p id="error-message" class="text-[13px] text-red-600 dark:text-red-400 mt-2 p-3 bg-red-50 dark:bg-red-950/50 rounded border-l-[3px] border-red-600"></p> 75 - <button id="btn-retry" class="w-full bg-white dark:bg-purple-950 text-purple-700 dark:text-cyan-400 border-2 border-purple-700 dark:border-cyan-400 font-semibold py-2.5 px-6 rounded-lg mt-4 transition-all duration-200 hover:bg-purple-50 dark:hover:bg-purple-900"> 122 + <p 123 + class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50" 124 + > 125 + Error 126 + </p> 127 + <p 128 + id="error-message" 129 + class="text-[13px] text-red-600 dark:text-red-400 mt-2 p-3 bg-red-50 dark:bg-red-950/50 rounded border-l-[3px] border-red-600" 130 + ></p> 131 + <button 132 + id="btn-retry" 133 + class="w-full bg-white dark:bg-purple-950 text-purple-700 dark:text-cyan-400 border-2 border-purple-700 dark:border-cyan-400 font-semibold py-2.5 px-6 rounded-lg mt-4 transition-all duration-200 hover:bg-purple-50 dark:hover:bg-purple-900" 134 + > 76 135 Try Again 77 136 </button> 78 137 </div> ··· 80 139 <!-- Server offline state --> 81 140 <div id="state-offline" class="w-full text-center hidden"> 82 141 <div class="text-5xl mb-4">🔌</div> 83 - <p class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50">Server not available</p> 84 - <p id="dev-instructions" class="text-[13px] text-red-600 dark:text-red-400 mt-2 p-3 bg-red-50 dark:bg-red-950/50 rounded border-l-[3px] border-red-600"> 142 + <p 143 + class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50" 144 + > 145 + Server not available 146 + </p> 147 + <p 148 + id="dev-instructions" 149 + class="text-[13px] text-red-600 dark:text-red-400 mt-2 p-3 bg-red-50 dark:bg-red-950/50 rounded border-l-[3px] border-red-600" 150 + > 85 151 Start the dev server:<br /> 86 - <code class="bg-black/10 dark:bg-white/10 px-2 py-1 rounded font-mono text-[11px] inline-block my-2">npx netlify-cli dev --filter @atlast/web</code> 152 + <code 153 + class="bg-black/10 dark:bg-white/10 px-2 py-1 rounded font-mono text-[11px] inline-block my-2" 154 + >npx netlify-cli dev --filter @atlast/web</code 155 + > 87 156 </p> 88 - <p class="text-[13px] text-slate-500 dark:text-slate-400 mt-2" id="server-url"></p> 89 - <button id="btn-check-server" class="w-full bg-orange-600 hover:bg-orange-700 text-white font-semibold py-3 px-6 rounded-lg mt-4 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-lg hover:shadow-orange-600/30 active:translate-y-0"> 157 + <p 158 + class="text-[13px] text-slate-500 dark:text-slate-400 mt-2" 159 + id="server-url" 160 + ></p> 161 + <button 162 + id="btn-check-server" 163 + class="w-full bg-orange-600 hover:bg-orange-700 text-white font-semibold py-3 px-6 rounded-lg mt-4 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-lg hover:shadow-orange-600/30 active:translate-y-0" 164 + > 90 165 Check Again 91 166 </button> 92 167 </div> ··· 94 169 <!-- Not logged in state --> 95 170 <div id="state-not-logged-in" class="w-full text-center hidden"> 96 171 <div class="text-5xl mb-4">🔐</div> 97 - <p class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50">Not logged in to ATlast</p> 98 - <p class="text-[13px] text-red-600 dark:text-red-400 mt-2 p-3 bg-red-50 dark:bg-red-950/50 rounded border-l-[3px] border-red-600"> 172 + <p 173 + class="text-base font-semibold mb-3 text-slate-700 dark:text-cyan-50" 174 + > 175 + Not logged in to ATlast 176 + </p> 177 + <p 178 + class="text-[13px] text-red-600 dark:text-red-400 mt-2 p-3 bg-red-50 dark:bg-red-950/50 rounded border-l-[3px] border-red-600" 179 + > 99 180 Please log in to ATlast first, then return here to scan. 100 181 </p> 101 - <button id="btn-open-atlast" class="w-full bg-orange-600 hover:bg-orange-700 text-white font-semibold py-3 px-6 rounded-lg mt-4 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-lg hover:shadow-orange-600/30 active:translate-y-0"> 182 + <button 183 + id="btn-open-atlast" 184 + class="w-full bg-orange-600 hover:bg-orange-700 text-white font-semibold py-3 px-6 rounded-lg mt-4 transition-all duration-200 hover:-translate-y-0.5 hover:shadow-lg hover:shadow-orange-600/30 active:translate-y-0" 185 + > 102 186 Open ATlast 103 187 </button> 104 - <button id="btn-retry-login" class="w-full bg-white dark:bg-purple-950 text-purple-700 dark:text-cyan-400 border-2 border-purple-700 dark:border-cyan-400 font-semibold py-2.5 px-6 rounded-lg mt-4 transition-all duration-200 hover:bg-purple-50 dark:hover:bg-purple-900"> 188 + <button 189 + id="btn-retry-login" 190 + class="w-full bg-white dark:bg-purple-950 text-purple-700 dark:text-cyan-400 border-2 border-purple-700 dark:border-cyan-400 font-semibold py-2.5 px-6 rounded-lg mt-4 transition-all duration-200 hover:bg-purple-50 dark:hover:bg-purple-900" 191 + > 105 192 Check Again 106 193 </button> 107 194 </div> 108 195 </main> 109 196 110 - <footer class="p-4 text-center border-t border-purple-200 dark:border-slate-800 bg-white dark:bg-slate-900"> 111 - <a href="https://atlast.byarielm.fyi" target="_blank" class="text-orange-600 dark:text-orange-400 no-underline text-[13px] font-medium hover:underline">atlast.byarielm.fyi</a> 197 + <footer 198 + class="p-4 text-center border-t border-purple-200 dark:border-slate-800 bg-white dark:bg-slate-900" 199 + > 200 + <a 201 + href="https://atlast.byarielm.fyi" 202 + target="_blank" 203 + class="text-orange-600 dark:text-orange-400 no-underline text-[13px] font-medium hover:underline" 204 + >atlast.byarielm.fyi</a 205 + > 112 206 </footer> 113 207 </div> 114 208