Thread viewer for Bluesky

Compare changes

Choose any two refs to compare.

+10
index.html
··· 49 49 50 50 <li><a href="#" data-action="login">Log in</a></li> 51 51 <li><a href="#" data-action="logout">Log out</a></li> 52 + 53 + <li class="link"><a href="?">Home</a></li> 54 + <li class="link"><a href="?page=posting_stats">Posting stats</a></li> 55 + <li class="link"><a href="?page=like_stats">Like stats</a></li> 56 + <li class="link"><a href="?page=search">Timeline search</a></li> 57 + <li class="link"><a href="?page=search&mode=likes">Archive search</a></li> 52 58 </ul> 53 59 </div> 54 60 ··· 195 201 196 202 <div class="lycan-import"> 197 203 <form> 204 + <h4>Data not imported yet</h4> 205 + 198 206 <p> 199 207 In order to search within your likes and bookmarks, the posts you've liked or saved need to be imported into a database. 200 208 This is a one-time process, but it can take several minutes or more, depending on the age of your account. ··· 209 217 </form> 210 218 211 219 <div class="import-progress"> 220 + <h4>Import in progress</h4> 221 + 212 222 <p class="import-status"></p> 213 223 <p><progress></progress> <output></output></p> 214 224 </div>
+8 -1
menu.js
··· 11 11 12 12 html.addEventListener('click', (e) => { 13 13 this.menuElement.style.visibility = 'hidden'; 14 + this.icon.classList.remove('active'); 14 15 }); 16 + 17 + let homeLink = $(this.menuElement.querySelector('a[href="?"]'), HTMLLinkElement); 18 + homeLink.href = location.origin + location.pathname; 15 19 16 20 this.icon.addEventListener('click', (e) => { 17 21 e.stopPropagation(); ··· 66 70 } 67 71 68 72 toggleAccountMenu() { 69 - this.menuElement.style.visibility = (this.menuElement.style.visibility == 'visible') ? 'hidden' : 'visible'; 73 + let isVisible = (this.menuElement.style.visibility == 'visible'); 74 + 75 + this.menuElement.style.visibility = isVisible ? 'hidden' : 'visible'; 76 + this.icon.classList.toggle('active', !isVisible); 70 77 } 71 78 72 79 /** @param {string} buttonName */
+14 -6
private_search_page.js
··· 42 42 43 43 let params = new URLSearchParams(location.search); 44 44 this.mode = params.get('mode'); 45 - this.lycanMode = params.get('lycan'); 45 + let lycan = params.get('lycan'); 46 46 47 - if (this.lycanMode == 'local') { 47 + if (lycan == 'local') { 48 48 this.localLycan = new BlueskyAPI('http://localhost:3000', false); 49 + } else if (lycan) { 50 + this.lycanAddress = `did:web:${lycan}#lycan`; 51 + } else { 52 + this.lycanAddress = 'did:web:lycan.feeds.blue#lycan'; 49 53 } 50 54 } 51 55 ··· 136 140 return await this.localLycan.getRequest('blue.feeds.lycan.getImportStatus', { user: accountAPI.user.did }); 137 141 } else { 138 142 return await accountAPI.getRequest('blue.feeds.lycan.getImportStatus', null, { 139 - headers: { 'atproto-proxy': 'did:web:lycan.feeds.blue#lycan' } 143 + headers: { 'atproto-proxy': this.lycanAddress } 140 144 }); 141 145 } 142 146 } ··· 157 161 this.lycanImportSection.style.display = 'block'; 158 162 this.lycanImportForm.style.display = 'block'; 159 163 this.importProgress.style.display = 'none'; 164 + this.searchField.disabled = true; 160 165 161 166 this.stopImportTimer(); 162 167 } else if (info.status == 'in_progress' || info.status == 'scheduled' || info.status == 'requested') { 163 168 this.lycanImportSection.style.display = 'block'; 164 169 this.lycanImportForm.style.display = 'none'; 165 170 this.importProgress.style.display = 'block'; 171 + this.searchField.disabled = true; 166 172 167 173 this.showImportProgress(info); 168 174 this.startImportTimer(); 169 175 } else if (info.status == 'finished') { 170 176 this.lycanImportForm.style.display = 'none'; 171 177 this.importProgress.style.display = 'block'; 178 + this.searchField.disabled = false; 172 179 173 180 this.showImportProgress({ status: 'finished', progress: 1.0 }); 174 181 this.stopImportTimer(); ··· 192 199 this.importStatusLabel.innerText = `Import complete โœ“`; 193 200 } else if (info.position) { 194 201 let date = new Date(info.position).toLocaleString(window.dateLocale, { day: 'numeric', month: 'short', year: 'numeric' }); 195 - this.importStatusLabel.innerText = `Imported data until: ${date}`; 202 + this.importStatusLabel.innerText = `Downloaded data until: ${date}`; 196 203 } else if (info.status == 'requested') { 197 204 this.importStatusLabel.innerText = 'Requesting importโ€ฆ'; 198 205 } else { ··· 206 213 this.lycanImportSection.style.display = 'block'; 207 214 this.lycanImportForm.style.display = 'none'; 208 215 this.importProgress.style.display = 'block'; 216 + this.searchField.disabled = true; 209 217 210 218 this.importStatusLabel.innerText = message; 211 219 this.stopImportTimer(); ··· 240 248 }); 241 249 } else { 242 250 await accountAPI.postRequest('blue.feeds.lycan.startImport', null, { 243 - headers: { 'atproto-proxy': 'did:web:lycan.feeds.blue#lycan' } 251 + headers: { 'atproto-proxy': this.lycanAddress } 244 252 }); 245 253 } 246 254 ··· 354 362 if (cursor) params.cursor = cursor; 355 363 356 364 response = await accountAPI.getRequest('blue.feeds.lycan.searchPosts', params, { 357 - headers: { 'atproto-proxy': 'did:web:lycan.feeds.blue#lycan' } 365 + headers: { 'atproto-proxy': this.lycanAddress } 358 366 }); 359 367 } 360 368
+24 -4
style.css
··· 127 127 padding: 6px 11px; 128 128 } 129 129 130 - #account_menu li a { 130 + #account_menu li a[data-action] { 131 131 display: inline-block; 132 132 color: #333; 133 133 font-size: 11pt; ··· 138 138 background-color: hsla(210, 100%, 4%, 0.12); 139 139 } 140 140 141 - #account_menu li a:hover { 141 + #account_menu li a[data-action]:hover { 142 142 background-color: hsla(210, 100%, 4%, 0.2); 143 143 text-decoration: none; 144 + } 145 + 146 + #account_menu li:not(.link) + li.link { 147 + margin-top: 16px; 148 + padding-top: 10px; 149 + border-top: 1px solid #ccc; 150 + } 151 + 152 + #account_menu li.link { 153 + margin-top: 8px; 154 + margin-left: 2px; 155 + } 156 + 157 + #account_menu li.link a { 158 + font-size: 11pt; 159 + color: #333; 144 160 } 145 161 146 162 #account_menu li .check { ··· 1142 1158 background-color: transparent; 1143 1159 } 1144 1160 1161 + #account.active { 1162 + color: #333; 1163 + } 1164 + 1145 1165 #account_menu { 1146 1166 background: hsl(210, 33.33%, 94.0%); 1147 1167 border-color: #ccc; 1148 1168 } 1149 1169 1150 - #account_menu li a { 1170 + #account_menu li a[data-action] { 1151 1171 color: #333; 1152 1172 border-color: #bbb; 1153 1173 background-color: hsla(210, 100%, 4%, 0.12); 1154 1174 } 1155 1175 1156 - #account_menu li a:hover { 1176 + #account_menu li a[data-action]:hover { 1157 1177 background-color: hsla(210, 100%, 4%, 0.2); 1158 1178 } 1159 1179