Thread viewer for Bluesky
at master 8.9 kB view raw
1<!DOCTYPE html> 2<html> 3<head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="Content-Security-Policy" content=" 6 default-src 'none'; 7 script-src 'self' 'sha256-C5RUxaoIkpRux1/UhIgLL5RalHWo6EOGHzWOhCMr8Fs='; 8 style-src 'self'; 9 img-src 'self' https:; 10 font-src 'self'; 11 script-src-attr 'none'; 12 style-src-attr 'none'; 13 connect-src https: http://localhost:3000; 14 base-uri 'none'; 15 form-action 'none';"> 16 17 <title>Skythread</title> 18 <link href="./fontawesome/fontawesome.min.css" rel="stylesheet"> 19 <link href="./fontawesome/solid.min.css" rel="stylesheet"> 20 <link href="./fontawesome/regular.min.css" rel="stylesheet"> 21 <link href="style.css" rel="stylesheet"> 22</head> 23<body> 24 <div id="loader"><img src="icons/sunny.png"></div> 25 26 <div id="search"> 27 <form method="get"> 28 🌤 <input type="text" placeholder="Paste a thread link or type a #hashtag" name="q"> 29 </form> 30 </div> 31 32 <div id="github"> 33 <a href="https://github.com/mackuba/skythread" target="_blank"> 34 <img src="icons/github.png"> 35 </a> 36 </div> 37 38 <div id="account"> 39 <i class="fa-regular fa-user-circle fa-xl"></i> 40 </div> 41 42 <div id="account_menu"> 43 <ul> 44 <li><a href="#" data-action="incognito" 45 title="Temporarily load threads as a logged-out user"><span class="check"></span>Incognito mode</a></li> 46 47 <li><a href="#" data-action="biohazard" 48 title="Show links to blocked and hidden comments"><span class="check"></span>Show infohazards</a></li> 49 50 <li><a href="#" data-action="login">Log in</a></li> 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> 58 </ul> 59 </div> 60 61 <div id="thread"> 62 </div> 63 64 <div id="login" class="dialog"> 65 <form method="get"> 66 <i class="close fa-circle-xmark fa-regular"></i> 67 <h2>🌤 Skythread</h2> 68 <p><input type="text" id="login_handle" required placeholder="name.bsky.social"></p> 69 <p><input type="password" id="login_password" required 70 placeholder="&#x2731;&#x2731;&#x2731;&#x2731;&#x2731;&#x2731;&#x2731;&#x2731;"></p> 71 <p class="info"><a href="#"><i class="fa-regular fa-circle-question"></i> Use an "app password" here</a></p> 72 <div class="info-box"> 73 <p>Bluesky API currently doesn't allow apps to request fine-grained permissions, only access to the whole account. However, you can generate an "app password" in the Bluesky app settings for this specific app that you can later revoke at any time.</p> 74 <p>The password you enter here is only passed to the Bluesky API and isn't saved anywhere. The returned access token is only stored in your browser's local storage. You can see the complete source code of this app <a href="http://github.com/mackuba/skythread" target="_blank">on GitHub</a>.</p> 75 </div> 76 <p class="submit"> 77 <input id="login_submit" type="submit" value="Log in"> 78 <i id="cloudy" class="fa-solid fa-cloud fa-beat fa-xl"></i> 79 </p> 80 </form> 81 </div> 82 83 <div id="biohazard_dialog" class="dialog"> 84 <form method="get"> 85 <i class="close fa-circle-xmark fa-regular"></i> 86 <h2>☣️ Infohazard Warning</h2> 87 <p>&ldquo;<em>This thread is not a place of honor... no highly esteemed post is commemorated here... nothing valued is here.</em>&rdquo;</p> 88 <p>This feature allows access to comments in a thread which were hidden because one of the commenters has blocked another. Bluesky currently hides such comments to avoid escalating conflicts.</p> 89 <p>Are you sure you want to enter?<br>(You can toggle this in the menu in top-left corner.)</p> 90 <p class="submit"> 91 <input type="submit" id="biohazard_show" value="Show me the drama 😈"> 92 <input type="submit" id="biohazard_hide" value="Nope, I'd rather not 🙈"> 93 </p> 94 </form> 95 </div> 96 97 <div id="posting_stats_page"> 98 <h2>Bluesky posting statistics</h2> 99 100 <form> 101 <p> 102 Scan posts from: 103 <input type="radio" name="scan_type" id="scan_type_timeline" value="home" checked> 104 <label for="scan_type_timeline">Home timeline</label> 105 106 <input type="radio" name="scan_type" id="scan_type_list" value="list"> 107 <label for="scan_type_list">List feed</label> 108 109 <input type="radio" name="scan_type" id="scan_type_users" value="users"> 110 <label for="scan_type_users">Selected users</label> 111 112 <input type="radio" name="scan_type" id="scan_type_you" value="you"> 113 <label for="scan_type_you">Your profile</label> 114 </p> 115 116 <p> 117 Time range: <input type="range" min="1" max="60" value="7"> <label>7 days</label> 118 </p> 119 120 <p class="list-choice"> 121 <label>Select list:</label> 122 <select name="scan_list"></select> 123 </p> 124 125 <div class="user-choice"> 126 <input type="text" placeholder="Add user" autocomplete="off"> 127 <div class="autocomplete"></div> 128 <div class="selected-users"></div> 129 </div> 130 131 <p> 132 <input type="submit" value="Start scan"> <progress></progress> 133 </p> 134 </form> 135 136 <p class="scan-info"></p> 137 138 <table class="scan-result"> 139 <thead></thead> 140 <tbody></tbody> 141 </table> 142 </div> 143 144 <div id="like_stats_page"> 145 <h2>Like statistics</h2> 146 147 <form> 148 <p> 149 Time range: <input type="range" min="1" max="60" value="7"> <label>7 days</label> 150 </p> 151 152 <p> 153 <input type="submit" value="Start scan"> <progress></progress> 154 </p> 155 </form> 156 157 <table class="scan-result given-likes"> 158 <thead> 159 <tr><th colspan="3">❤️ Likes from you:</th></tr> 160 </thead> 161 <tbody></tbody> 162 </table> 163 164 <table class="scan-result received-likes"> 165 <thead> 166 <tr><th colspan="3">💛 Likes on your posts:</th></tr> 167 </thead> 168 <tbody></tbody> 169 </table> 170 </div> 171 172 <div id="private_search_page"> 173 <h2>Archive search</h2> 174 175 <div class="timeline-search"> 176 <form> 177 <p> 178 Fetch timeline posts: <input type="range" min="1" max="60" value="7"> <label>7 days</label> 179 </p> 180 181 <p> 182 <input type="submit" value="Fetch timeline"> <progress></progress> 183 </p> 184 </form> 185 186 <p class="archive-status"></p> 187 188 <hr> 189 </div> 190 191 <form class="search-form"> 192 <p class="search">Search: <input type="text" class="search-query" autocomplete="off"></p> 193 194 <div class="search-collections"> 195 <input type="radio" name="collection" value="likes" id="collection-likes" checked> <label for="collection-likes">Likes</label> 196 <input type="radio" name="collection" value="reposts" id="collection-reposts"> <label for="collection-reposts">Reposts</label> 197 <input type="radio" name="collection" value="quotes" id="collection-quotes"> <label for="collection-quotes">Quotes</label> 198 <input type="radio" name="collection" value="pins" id="collection-pins"> <label for="collection-pins">Pins</label> 199 </div> 200 </form> 201 202 <div class="lycan-import"> 203 <form> 204 <h4>Data not imported yet</h4> 205 206 <p> 207 In order to search within your likes and bookmarks, the posts you've liked or saved need to be imported into a database. 208 This is a one-time process, but it can take several minutes or more, depending on the age of your account. 209 </p> 210 <p> 211 To start the import, press the button below. You can then wait until it finishes, or close this tab and come back a bit later. 212 After the import is complete, the database will be kept up to date automatically going forward. 213 </p> 214 <p> 215 <input type="submit" value="Start import"> 216 </p> 217 </form> 218 219 <div class="import-progress"> 220 <h4>Import in progress</h4> 221 222 <p class="import-status"></p> 223 <p><progress></progress> <output></output></p> 224 </div> 225 </div> 226 227 <div class="results"> 228 </div> 229 </div> 230 231 <script src="lib/purify.min.js"></script> 232 <script src="minisky.js"></script> 233 <script src="api.js"></script> 234 <script src="utils.js"></script> 235 <script src="rich_text_lite.js"></script> 236 <script src="models.js"></script> 237 <script src="menu.js"></script> 238 <script src="thread_page.js"></script> 239 <script src="posting_stats_page.js"></script> 240 <script src="like_stats_page.js"></script> 241 <script src="notifications_page.js"></script> 242 <script src="private_search_page.js"></script> 243 <script src="embed_component.js"></script> 244 <script src="post_component.js"></script> 245 <script src="skythread.js"></script> 246 247 <script> 248 init(); 249 </script> 250</body> 251</html>