mobile bluesky app made with flutter lazurite.stormlightlabs.org/
mobile bluesky flutter
3
fork

Configure Feed

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

at main 633 lines 21 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, maximum-scale=1.0, user-scalable=no" /> 6 <title>Dev Tools - Lazurite</title> 7 <link rel="preconnect" href="https://fonts.googleapis.com" /> 8 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> 9 <link 10 href="https://fonts.googleapis.com/css2?family=Lora:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" 11 rel="stylesheet" /> 12 <link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap" rel="stylesheet"> 13 <link rel="stylesheet" href="styles.css" /> 14 <style> 15 .devtools-container { 16 padding-bottom: 88px; 17 } 18 19 .devtools-search { 20 padding: 16px; 21 border-bottom: 1px solid var(--border); 22 } 23 24 .devtools-search-row { 25 display: flex; 26 gap: 8px; 27 } 28 29 .devtools-search-row .input { 30 flex: 1; 31 font-family: "JetBrains Mono", monospace; 32 font-size: 13px; 33 } 34 35 .devtools-search-btn { 36 padding: 12px 16px; 37 border-radius: 8px; 38 border: none; 39 background-color: var(--accent-primary); 40 color: white; 41 font-weight: 600; 42 font-size: 14px; 43 cursor: pointer; 44 transition: background-color 0.2s ease; 45 white-space: nowrap; 46 } 47 48 .devtools-search-btn:hover { 49 background-color: var(--accent-primary-hover); 50 } 51 52 .devtools-tabs { 53 display: flex; 54 border-bottom: 1px solid var(--border); 55 background-color: var(--bg); 56 } 57 58 .devtools-tab { 59 flex: 1; 60 padding: 12px; 61 text-align: center; 62 font-weight: 600; 63 font-size: 13px; 64 color: var(--text-secondary); 65 cursor: pointer; 66 border-bottom: 2px solid transparent; 67 transition: all 0.2s ease; 68 background: none; 69 border-top: none; 70 border-left: none; 71 border-right: none; 72 } 73 74 .devtools-tab:hover { 75 background-color: var(--surface); 76 color: var(--text-primary); 77 } 78 79 .devtools-tab.active { 80 color: var(--text-primary); 81 border-bottom-color: var(--accent-primary); 82 } 83 84 /* Repo Overview */ 85 .repo-header { 86 padding: 16px; 87 border-bottom: 1px solid var(--border); 88 background-color: var(--surface); 89 } 90 91 .repo-identity { 92 display: flex; 93 align-items: center; 94 gap: 12px; 95 margin-bottom: 12px; 96 } 97 98 .repo-avatar { 99 width: 40px; 100 height: 40px; 101 border-radius: 50%; 102 background-color: var(--surface-variant); 103 display: flex; 104 align-items: center; 105 justify-content: center; 106 font-weight: 600; 107 font-size: 14px; 108 color: var(--text-secondary); 109 flex-shrink: 0; 110 } 111 112 .repo-names { 113 flex: 1; 114 min-width: 0; 115 } 116 117 .repo-handle { 118 font-weight: 600; 119 font-size: 15px; 120 color: var(--text-primary); 121 } 122 123 .repo-did { 124 font-family: "JetBrains Mono", monospace; 125 font-size: 11px; 126 color: var(--text-muted); 127 overflow: hidden; 128 text-overflow: ellipsis; 129 white-space: nowrap; 130 } 131 132 .repo-stats { 133 display: flex; 134 gap: 16px; 135 } 136 137 .repo-stat { 138 font-size: 13px; 139 color: var(--text-secondary); 140 } 141 142 .repo-stat strong { 143 color: var(--text-primary); 144 font-weight: 600; 145 } 146 147 /* Collection List */ 148 .collection-item { 149 display: flex; 150 align-items: center; 151 justify-content: space-between; 152 padding: 14px 16px; 153 border-bottom: 1px solid var(--border); 154 cursor: pointer; 155 transition: background-color 0.2s ease; 156 } 157 158 .collection-item:hover { 159 background-color: var(--surface); 160 } 161 162 .collection-item-left { 163 display: flex; 164 align-items: center; 165 gap: 12px; 166 min-width: 0; 167 flex: 1; 168 } 169 170 .collection-icon { 171 width: 32px; 172 height: 32px; 173 border-radius: 6px; 174 background-color: var(--surface); 175 border: 1px solid var(--border); 176 display: flex; 177 align-items: center; 178 justify-content: center; 179 flex-shrink: 0; 180 } 181 182 .collection-icon svg { 183 width: 16px; 184 height: 16px; 185 color: var(--text-secondary); 186 } 187 188 .collection-name { 189 font-family: "JetBrains Mono", monospace; 190 font-size: 13px; 191 font-weight: 500; 192 color: var(--text-primary); 193 overflow: hidden; 194 text-overflow: ellipsis; 195 white-space: nowrap; 196 } 197 198 .collection-count { 199 font-size: 12px; 200 color: var(--text-muted); 201 background-color: var(--surface); 202 padding: 2px 8px; 203 border-radius: 9999px; 204 flex-shrink: 0; 205 } 206 207 .collection-chevron { 208 color: var(--text-muted); 209 flex-shrink: 0; 210 margin-left: 8px; 211 } 212 213 .collection-chevron svg { 214 width: 16px; 215 height: 16px; 216 } 217 218 /* Record Inspector */ 219 .record-header { 220 padding: 12px 16px; 221 background-color: var(--surface); 222 border-bottom: 1px solid var(--border); 223 display: flex; 224 align-items: center; 225 justify-content: space-between; 226 } 227 228 .record-breadcrumb { 229 font-family: "JetBrains Mono", monospace; 230 font-size: 12px; 231 color: var(--text-secondary); 232 overflow: hidden; 233 text-overflow: ellipsis; 234 white-space: nowrap; 235 } 236 237 .record-breadcrumb span { 238 color: var(--accent-primary); 239 } 240 241 .record-copy-btn { 242 padding: 4px 10px; 243 border-radius: 4px; 244 border: 1px solid var(--border); 245 background-color: var(--bg); 246 color: var(--text-secondary); 247 font-size: 11px; 248 font-weight: 500; 249 cursor: pointer; 250 transition: all 0.2s ease; 251 } 252 253 .record-copy-btn:hover { 254 background-color: var(--surface-variant); 255 color: var(--text-primary); 256 } 257 258 .json-viewer { 259 padding: 16px; 260 font-family: "JetBrains Mono", monospace; 261 font-size: 12px; 262 line-height: 1.8; 263 overflow-x: auto; 264 } 265 266 .json-key { 267 color: var(--accent-primary); 268 } 269 .json-string { 270 color: var(--accent-success); 271 } 272 .json-number { 273 color: var(--accent-secondary); 274 } 275 .json-bool { 276 color: var(--accent-warning); 277 } 278 .json-null { 279 color: var(--text-muted); 280 } 281 .json-brace { 282 color: var(--text-secondary); 283 } 284 285 /* Section Label */ 286 .section-label { 287 padding: 8px 16px; 288 font-size: 12px; 289 font-weight: 600; 290 color: var(--text-muted); 291 text-transform: uppercase; 292 letter-spacing: 0.5px; 293 background-color: var(--surface); 294 border-bottom: 1px solid var(--border); 295 } 296 </style> 297 </head> 298 <body> 299 <div class="mobile-container"> 300 <!-- Header --> 301 <header class="header"> 302 <button class="header-action">← Back</button> 303 <h1 class="header-title">PDS Explorer</h1> 304 <button class="header-action"></button> 305 </header> 306 307 <!-- Search / AT-URI Input --> 308 <div class="devtools-search"> 309 <div class="devtools-search-row"> 310 <input class="input" type="text" placeholder="Handle, DID, or at:// URI" value="alice.bsky.social" /> 311 <button class="devtools-search-btn">Resolve</button> 312 </div> 313 </div> 314 315 <!-- Tabs --> 316 <div class="devtools-tabs"> 317 <button class="devtools-tab active">Repo</button> 318 <button class="devtools-tab">Records</button> 319 <button class="devtools-tab">JSON</button> 320 </div> 321 322 <div class="devtools-container"> 323 <!-- Repo Overview --> 324 <div class="repo-header"> 325 <div class="repo-identity"> 326 <div class="repo-avatar">AS</div> 327 <div class="repo-names"> 328 <div class="repo-handle">alice.bsky.social</div> 329 <div class="repo-did">did:plc:z72i7hdynmk6r22z27h6tvur</div> 330 </div> 331 </div> 332 <div class="repo-stats"> 333 <div class="repo-stat"><strong>12</strong> collections</div> 334 <div class="repo-stat"><strong>1,847</strong> records</div> 335 </div> 336 </div> 337 338 <!-- Collections --> 339 <div class="section-label">Collections</div> 340 341 <div class="collection-item"> 342 <div class="collection-item-left"> 343 <div class="collection-icon"> 344 <svg 345 viewBox="0 0 24 24" 346 fill="none" 347 stroke="currentColor" 348 stroke-width="2" 349 stroke-linecap="round" 350 stroke-linejoin="round"> 351 <path 352 d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" /> 353 </svg> 354 </div> 355 <div class="collection-name">app.bsky.feed.post</div> 356 </div> 357 <span class="collection-count">482</span> 358 <div class="collection-chevron"> 359 <svg 360 viewBox="0 0 24 24" 361 fill="none" 362 stroke="currentColor" 363 stroke-width="2" 364 stroke-linecap="round" 365 stroke-linejoin="round"> 366 <polyline points="9 18 15 12 9 6" /> 367 </svg> 368 </div> 369 </div> 370 371 <div class="collection-item"> 372 <div class="collection-item-left"> 373 <div class="collection-icon"> 374 <svg 375 viewBox="0 0 24 24" 376 fill="none" 377 stroke="currentColor" 378 stroke-width="2" 379 stroke-linecap="round" 380 stroke-linejoin="round"> 381 <path 382 d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" /> 383 </svg> 384 </div> 385 <div class="collection-name">app.bsky.feed.like</div> 386 </div> 387 <span class="collection-count">1,203</span> 388 <div class="collection-chevron"> 389 <svg 390 viewBox="0 0 24 24" 391 fill="none" 392 stroke="currentColor" 393 stroke-width="2" 394 stroke-linecap="round" 395 stroke-linejoin="round"> 396 <polyline points="9 18 15 12 9 6" /> 397 </svg> 398 </div> 399 </div> 400 401 <div class="collection-item"> 402 <div class="collection-item-left"> 403 <div class="collection-icon"> 404 <svg 405 viewBox="0 0 24 24" 406 fill="none" 407 stroke="currentColor" 408 stroke-width="2" 409 stroke-linecap="round" 410 stroke-linejoin="round"> 411 <polyline points="17 1 21 5 17 9" /> 412 <path d="M3 11V9a4 4 0 0 1 4-4h14" /> 413 <polyline points="7 23 3 19 7 15" /> 414 <path d="M21 13v2a4 4 0 0 1-4 4H3" /> 415 </svg> 416 </div> 417 <div class="collection-name">app.bsky.feed.repost</div> 418 </div> 419 <span class="collection-count">89</span> 420 <div class="collection-chevron"> 421 <svg 422 viewBox="0 0 24 24" 423 fill="none" 424 stroke="currentColor" 425 stroke-width="2" 426 stroke-linecap="round" 427 stroke-linejoin="round"> 428 <polyline points="9 18 15 12 9 6" /> 429 </svg> 430 </div> 431 </div> 432 433 <div class="collection-item"> 434 <div class="collection-item-left"> 435 <div class="collection-icon"> 436 <svg 437 viewBox="0 0 24 24" 438 fill="none" 439 stroke="currentColor" 440 stroke-width="2" 441 stroke-linecap="round" 442 stroke-linejoin="round"> 443 <path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" /> 444 <circle cx="8.5" cy="7" r="4" /> 445 <line x1="20" y1="8" x2="20" y2="14" /> 446 <line x1="23" y1="11" x2="17" y2="11" /> 447 </svg> 448 </div> 449 <div class="collection-name">app.bsky.graph.follow</div> 450 </div> 451 <span class="collection-count">256</span> 452 <div class="collection-chevron"> 453 <svg 454 viewBox="0 0 24 24" 455 fill="none" 456 stroke="currentColor" 457 stroke-width="2" 458 stroke-linecap="round" 459 stroke-linejoin="round"> 460 <polyline points="9 18 15 12 9 6" /> 461 </svg> 462 </div> 463 </div> 464 465 <div class="collection-item"> 466 <div class="collection-item-left"> 467 <div class="collection-icon"> 468 <svg 469 viewBox="0 0 24 24" 470 fill="none" 471 stroke="currentColor" 472 stroke-width="2" 473 stroke-linecap="round" 474 stroke-linejoin="round"> 475 <circle cx="12" cy="12" r="10" /> 476 <line x1="2" y1="12" x2="22" y2="12" /> 477 <path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" /> 478 </svg> 479 </div> 480 <div class="collection-name">app.bsky.feed.generator</div> 481 </div> 482 <span class="collection-count">2</span> 483 <div class="collection-chevron"> 484 <svg 485 viewBox="0 0 24 24" 486 fill="none" 487 stroke="currentColor" 488 stroke-width="2" 489 stroke-linecap="round" 490 stroke-linejoin="round"> 491 <polyline points="9 18 15 12 9 6" /> 492 </svg> 493 </div> 494 </div> 495 496 <div class="collection-item"> 497 <div class="collection-item-left"> 498 <div class="collection-icon"> 499 <svg 500 viewBox="0 0 24 24" 501 fill="none" 502 stroke="currentColor" 503 stroke-width="2" 504 stroke-linecap="round" 505 stroke-linejoin="round"> 506 <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" /> 507 <circle cx="12" cy="7" r="4" /> 508 </svg> 509 </div> 510 <div class="collection-name">app.bsky.actor.profile</div> 511 </div> 512 <span class="collection-count">1</span> 513 <div class="collection-chevron"> 514 <svg 515 viewBox="0 0 24 24" 516 fill="none" 517 stroke="currentColor" 518 stroke-width="2" 519 stroke-linecap="round" 520 stroke-linejoin="round"> 521 <polyline points="9 18 15 12 9 6" /> 522 </svg> 523 </div> 524 </div> 525 526 <!-- Record Inspector Preview (shown when tapping a record) --> 527 <div class="section-label">Record Preview</div> 528 529 <div class="record-header"> 530 <div class="record-breadcrumb"><span>app.bsky.feed.post</span> / 3lbr7yz2gfk2j</div> 531 <button class="record-copy-btn">Copy JSON</button> 532 </div> 533 534 <div class="json-viewer"> 535 <span class="json-brace">{</span><br /> 536 &nbsp;&nbsp;<span class="json-key">"$type"</span>: 537 <span class="json-string">"app.bsky.feed.post"</span>,<br /> 538 &nbsp;&nbsp;<span class="json-key">"text"</span>: 539 <span class="json-string">"Just launched my new project! 🚀"</span>,<br /> 540 &nbsp;&nbsp;<span class="json-key">"createdAt"</span>: 541 <span class="json-string">"2024-03-15T14:30:00.000Z"</span>,<br /> 542 &nbsp;&nbsp;<span class="json-key">"langs"</span>: <span class="json-brace">[</span 543 ><span class="json-string">"en"</span><span class="json-brace">]</span>,<br /> 544 &nbsp;&nbsp;<span class="json-key">"facets"</span>: <span class="json-brace">[</span><br /> 545 &nbsp;&nbsp;&nbsp;&nbsp;<span class="json-brace">{</span><br /> 546 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="json-key">"index"</span>: <span class="json-brace">{</span 547 ><br /> 548 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="json-key">"byteStart"</span>: 549 <span class="json-number">0</span>,<br /> 550 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="json-key">"byteEnd"</span>: 551 <span class="json-number">34</span><br /> 552 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="json-brace">}</span>,<br /> 553 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="json-key">"features"</span>: <span class="json-brace">[</span 554 ><span class="json-brace">{</span><br /> 555 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="json-key">"$type"</span>: 556 <span class="json-string">"...facet#tag"</span>,<br /> 557 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="json-key">"tag"</span>: 558 <span class="json-string">"buildinpublic"</span><br /> 559 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="json-brace">}</span><span class="json-brace">]</span><br /> 560 &nbsp;&nbsp;&nbsp;&nbsp;<span class="json-brace">}</span><br /> 561 &nbsp;&nbsp;<span class="json-brace">]</span><br /> 562 <span class="json-brace">}</span> 563 </div> 564 </div> 565 566 <!-- Bottom Navigation --> 567 <nav class="nav-bar"> 568 <a href="home.html" class="nav-item"> 569 <svg 570 viewBox="0 0 24 24" 571 fill="none" 572 stroke="currentColor" 573 stroke-width="2" 574 stroke-linecap="round" 575 stroke-linejoin="round"> 576 <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" /> 577 <polyline points="9 22 9 12 15 12 15 22" /> 578 </svg> 579 <span>Home</span> 580 </a> 581 582 <a href="search.html" class="nav-item"> 583 <svg 584 viewBox="0 0 24 24" 585 fill="none" 586 stroke="currentColor" 587 stroke-width="2" 588 stroke-linecap="round" 589 stroke-linejoin="round"> 590 <circle cx="11" cy="11" r="8" /> 591 <line x1="21" y1="21" x2="16.65" y2="16.65" /> 592 </svg> 593 <span>Search</span> 594 </a> 595 596 <a href="profile.html" class="nav-item"> 597 <svg 598 viewBox="0 0 24 24" 599 fill="none" 600 stroke="currentColor" 601 stroke-width="2" 602 stroke-linecap="round" 603 stroke-linejoin="round"> 604 <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" /> 605 <circle cx="12" cy="7" r="4" /> 606 </svg> 607 <span>Profile</span> 608 </a> 609 610 <a href="settings.html" class="nav-item"> 611 <svg 612 viewBox="0 0 24 24" 613 fill="none" 614 stroke="currentColor" 615 stroke-width="2" 616 stroke-linecap="round" 617 stroke-linejoin="round"> 618 <circle cx="12" cy="12" r="3" /> 619 <path 620 d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" /> 621 </svg> 622 <span>Settings</span> 623 </a> 624 </nav> 625 </div> 626 627 <script> 628 if (localStorage.getItem("theme") === "dark") { 629 document.documentElement.setAttribute("data-theme", "dark"); 630 } 631 </script> 632 </body> 633</html>