This repository has no description
0

Configure Feed

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

add new features and styles

+1372 -36
+30 -16
src/components/Resources/Resources.css
··· 112 112 justify-content: space-between; 113 113 } 114 114 115 + /* Better category filter alignment */ 116 + .category-filters-container { 117 + width: 100%; 118 + overflow-x: auto; 119 + margin-bottom: 1rem; 120 + } 121 + 115 122 .category-filters { 116 123 display: flex; 117 - flex-wrap: wrap; 124 + flex-wrap: nowrap; 118 125 gap: 8px; 126 + padding-bottom: 0.5rem; 127 + min-width: max-content; 119 128 } 120 129 121 130 .category-filter { 131 + white-space: nowrap; 122 132 background-color: var(--card-border); 123 133 color: var(--text); 124 134 border: none; ··· 162 172 padding-bottom: 8px; 163 173 } 164 174 175 + /* Featured section description */ 176 + .featured-description { 177 + margin-top: -0.5rem; 178 + margin-bottom: 1.5rem; 179 + color: var(--text); 180 + font-style: italic; 181 + opacity: 0.8; 182 + } 183 + 165 184 .resources-grid { 166 185 display: grid; 167 186 grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); ··· 203 222 .resource-description { 204 223 font-size: 0.9rem; 205 224 color: var(--text); 206 - margin: 0 0 16px 0; 225 + margin: 0 0 8px 0; 207 226 flex-grow: 1; 208 227 opacity: 0.8; 209 228 } 210 229 230 + /* Resource domain styling */ 231 + .resource-domain { 232 + font-size: 0.85rem; 233 + color: var(--text); 234 + opacity: 0.7; 235 + margin: 0 0 16px 0; 236 + } 237 + 211 238 .resource-meta { 212 239 display: flex; 213 240 justify-content: space-between; ··· 302 329 align-items: flex-start; 303 330 } 304 331 305 - .category-filters { 306 - margin-bottom: 12px; 332 + .category-filters-container { 307 333 width: 100%; 308 - justify-content: flex-start; 309 334 } 310 335 311 336 .quality-filter { ··· 324 349 @media (max-width: 480px) { 325 350 .resources-page { 326 351 max-width: 100%; 327 - } 328 - 329 - .category-filters { 330 - display: flex; 331 - flex-wrap: wrap; 332 - } 333 - 334 - .category-filter { 335 - margin-bottom: 8px; 336 - width: calc(50% - 8px); 337 - text-align: center; 338 352 } 339 353 }
+1342 -20
src/components/Resources/Resources.js
··· 11 11 const [qualityFilter, setQualityFilter] = useState('All'); 12 12 const [isLoading, setIsLoading] = useState(true); 13 13 14 - // Resources data structure 14 + // Category emojis mapping 15 + const categoryEmojis = { 16 + 'All': '🔍', 17 + 'Analytics': '📊', 18 + 'Services': '🛠️', 19 + 'Data': '💾', 20 + 'Network': '🔄', 21 + 'Clients': '📱', 22 + 'Moderation': '🛡️', 23 + 'Feeds': '📰', 24 + 'Visualizations': '🎨', 25 + 'Development': '👨‍💻', 26 + 'Guides': '📚', 27 + 'Misc': '🔮' 28 + }; 29 + 30 + // Resources data structure with expanded items from the second file 15 31 const resourcesData = [ 16 32 // Analytics & Metrics - Personal Stats 17 33 { ··· 20 36 category: "Analytics", 21 37 subcategory: "Personal Stats", 22 38 description: "Check how consistently you use alt text", 39 + domain: "dame.is", 23 40 quality: 5, 24 41 featured: true 25 42 }, ··· 29 46 category: "Analytics", 30 47 subcategory: "Personal Stats", 31 48 description: "Use the KonMari method to sort through your old posts", 49 + domain: "skeet.tools", 32 50 quality: 5, 33 51 featured: true 34 52 }, ··· 38 56 category: "Analytics", 39 57 subcategory: "Personal Stats", 40 58 description: "Visualize your social graph", 59 + domain: "aviva.gay", 41 60 quality: 4, 42 61 featured: false 43 62 }, ··· 47 66 category: "Analytics", 48 67 subcategory: "Personal Stats", 49 68 description: "Profile metrics and fun stats", 69 + domain: "skyzoo.blue", 50 70 quality: 4, 51 71 featured: false 52 72 }, ··· 56 76 category: "Analytics", 57 77 subcategory: "Personal Stats", 58 78 description: "Bluesky analytics", 79 + domain: "skykit.blue", 59 80 quality: 4, 60 81 featured: true 61 82 }, 83 + { 84 + name: "Skeetstats", 85 + url: "https://bsky.app/profile/skeetstats.xyz", 86 + category: "Analytics", 87 + subcategory: "Personal Stats", 88 + description: "Track your Bluesky stats", 89 + domain: "skeetstats.xyz", 90 + quality: 3, 91 + featured: false 92 + }, 93 + { 94 + name: "Skircle", 95 + url: "http://skircle.me", 96 + category: "Analytics", 97 + subcategory: "Personal Stats", 98 + description: "Interaction circles visualization", 99 + domain: "skircle.me", 100 + quality: 3, 101 + featured: false 102 + }, 103 + { 104 + name: "Bluesky Counter", 105 + url: "https://blueskycounter.com/", 106 + category: "Analytics", 107 + subcategory: "Personal Stats", 108 + description: "Count various metrics for your profile", 109 + domain: "blueskycounter.com", 110 + quality: 3, 111 + featured: false 112 + }, 113 + { 114 + name: "ClearSky", 115 + url: "http://clearsky.app", 116 + category: "Analytics", 117 + subcategory: "Personal Stats", 118 + description: "Transparent block and list analytics", 119 + domain: "clearsky.app", 120 + quality: 4, 121 + featured: true 122 + }, 123 + { 124 + name: "Blueview", 125 + url: "https://blueview.app/login", 126 + category: "Analytics", 127 + subcategory: "Personal Stats", 128 + description: "Insights and analytics for your profile", 129 + domain: "blueview.app", 130 + quality: 4, 131 + featured: true 132 + }, 133 + { 134 + name: "Bskypt", 135 + url: "https://bskypt.vercel.app", 136 + category: "Analytics", 137 + subcategory: "Personal Stats", 138 + description: "Receipt-like profile stats", 139 + domain: "vercel.app", 140 + quality: 3, 141 + featured: false 142 + }, 143 + { 144 + name: "Posts Heatmap Generator", 145 + url: "https://bluesky-heatmap.fly.dev", 146 + category: "Analytics", 147 + subcategory: "Personal Stats", 148 + description: "Create a heatmap of your posting activity", 149 + domain: "fly.dev", 150 + quality: 3, 151 + featured: false 152 + }, 153 + { 154 + name: "Dopplersky", 155 + url: "https://dopplersky.com", 156 + category: "Analytics", 157 + subcategory: "Personal Stats", 158 + description: "Find your Twitter-to-Bluesky doppelgangers", 159 + domain: "dopplersky.com", 160 + quality: 3, 161 + featured: false 162 + }, 163 + { 164 + name: "Skystats", 165 + url: "https://skystats.mariozechner.at/", 166 + category: "Analytics", 167 + subcategory: "Personal Stats", 168 + description: "Comprehensive profile statistics", 169 + domain: "mariozechner.at", 170 + quality: 3, 171 + featured: false 172 + }, 173 + { 174 + name: "Best Time to Post", 175 + url: "https://bluesky.notemation.com/best-time-to-post", 176 + category: "Analytics", 177 + subcategory: "Personal Stats", 178 + description: "See your social graph's active times", 179 + domain: "notemation.com", 180 + quality: 3, 181 + featured: false 182 + }, 62 183 63 184 // Analytics & Metrics - Platform Stats 64 185 { ··· 67 188 category: "Analytics", 68 189 subcategory: "Platform Stats", 69 190 description: "Realtime user growth dashboard", 191 + domain: "nat.vg", 70 192 quality: 4, 71 193 featured: false 72 194 }, ··· 76 198 category: "Analytics", 77 199 subcategory: "Platform Stats", 78 200 description: "Real-time emoji usage data", 201 + domain: "bsky.sh", 202 + quality: 3, 203 + featured: false 204 + }, 205 + { 206 + name: "Bluesky Post Count and Author Stats", 207 + url: "https://bsky.jazco.dev/stats", 208 + category: "Analytics", 209 + subcategory: "Platform Stats", 210 + description: "Platform-wide statistics", 211 + domain: "jazco.dev", 212 + quality: 3, 213 + featured: false 214 + }, 215 + { 216 + name: "Bluesky Population Size Guide", 217 + url: "https://observablehq.com/d/58c2cd234ca376b8", 218 + category: "Analytics", 219 + subcategory: "Platform Stats", 220 + description: "Visual guide to Bluesky user population", 221 + domain: "observablehq.com", 222 + quality: 3, 223 + featured: false 224 + }, 225 + { 226 + name: "Top 500 Users List", 227 + url: "https://vqv.app/index.html", 228 + category: "Analytics", 229 + subcategory: "Platform Stats", 230 + description: "List of top Bluesky users by followers", 231 + domain: "vqv.app", 232 + quality: 3, 233 + featured: false 234 + }, 235 + { 236 + name: "Handles Directory", 237 + url: "https://blue.mackuba.eu/directory/", 238 + category: "Analytics", 239 + subcategory: "Platform Stats", 240 + description: "Browse Bluesky handles by domain", 241 + domain: "mackuba.eu", 242 + quality: 3, 243 + featured: false 244 + }, 245 + { 246 + name: "BlueTube", 247 + url: "https://bluetube.fyi/", 248 + category: "Analytics", 249 + subcategory: "Platform Stats", 250 + description: "Hottest YouTube links on Bluesky", 251 + domain: "bluetube.fyi", 252 + quality: 3, 253 + featured: false 254 + }, 255 + { 256 + name: "BSkyCharts", 257 + url: "https://bskycharts.edavis.dev/bluesky-day.html", 258 + category: "Analytics", 259 + subcategory: "Platform Stats", 260 + description: "Charts and statistics for Bluesky", 261 + domain: "edavis.dev", 79 262 quality: 3, 80 263 featured: false 81 264 }, ··· 87 270 category: "Services", 88 271 subcategory: "AppViews", 89 272 description: "Manage your muted words in bulk", 273 + domain: "mutesky.app", 90 274 quality: 4, 91 275 featured: false 92 276 }, ··· 96 280 category: "Services", 97 281 subcategory: "AppViews", 98 282 description: "Decentralized link aggregator", 283 + domain: "frontpage.fyi", 99 284 quality: 5, 100 285 featured: true 101 286 }, 102 287 { 103 - name: "Graze", 104 - url: "https://www.graze.social/", 105 - category: "Feeds", 106 - subcategory: "Feed Tools", 107 - description: "No-Code feed creator", 108 - quality: 5, 288 + name: "WhiteWind", 289 + url: "https://whtwnd.com/about", 290 + category: "Services", 291 + subcategory: "AppViews", 292 + description: "Markdown blogging service", 293 + domain: "whtwnd.com", 294 + quality: 4, 295 + featured: false 296 + }, 297 + { 298 + name: "Skylights", 299 + url: "https://skylights.my/profile/watwa.re", 300 + category: "Services", 301 + subcategory: "AppViews", 302 + description: "Track and review favorite media", 303 + domain: "skylights.my", 304 + quality: 4, 305 + featured: false 306 + }, 307 + { 308 + name: "BookHive", 309 + url: "https://bookhive.buzz/", 310 + category: "Services", 311 + subcategory: "AppViews", 312 + description: "Goodreads on AT Proto", 313 + domain: "bookhive.buzz", 314 + quality: 4, 315 + featured: false 316 + }, 317 + { 318 + name: "Linkat", 319 + url: "https://linkat.blue", 320 + category: "Services", 321 + subcategory: "AppViews", 322 + description: "Link in bio for Bluesky", 323 + domain: "linkat.blue", 324 + quality: 4, 325 + featured: false 326 + }, 327 + { 328 + name: "psky.social", 329 + url: "https://psky.social", 330 + category: "Services", 331 + subcategory: "AppViews", 332 + description: "Chatroom for Bluesky users", 333 + domain: "psky.social", 334 + quality: 3, 335 + featured: false 336 + }, 337 + { 338 + name: "atproto.camp", 339 + url: "https://atproto.camp", 340 + category: "Services", 341 + subcategory: "AppViews", 342 + description: "Earn badges for protocol activity", 343 + domain: "atproto.camp", 344 + quality: 3, 345 + featured: false 346 + }, 347 + { 348 + name: "pinksea.art", 349 + url: "https://pinksea.art/", 350 + category: "Services", 351 + subcategory: "AppViews", 352 + description: "Oekaki (doodle) on the ATprotocol", 353 + domain: "pinksea.art", 354 + quality: 4, 109 355 featured: true 110 356 }, 357 + { 358 + name: "poll.blue", 359 + url: "https://poll.blue/post", 360 + category: "Services", 361 + subcategory: "AppViews", 362 + description: "Polls for Bluesky", 363 + domain: "poll.blue", 364 + quality: 4, 365 + featured: false 366 + }, 367 + { 368 + name: "Blue Bots, Done Quick", 369 + url: "http://bluebotsdonequick.com", 370 + category: "Services", 371 + subcategory: "AppViews", 372 + description: "Create bots for Bluesky easily", 373 + domain: "bluebotsdonequick.com", 374 + quality: 3, 375 + featured: false 376 + }, 377 + { 378 + name: "teal.fm", 379 + url: "https://teal.fm", 380 + category: "Services", 381 + subcategory: "AppViews", 382 + description: "Music tracking and discovery", 383 + domain: "teal.fm", 384 + quality: 4, 385 + featured: false 386 + }, 387 + { 388 + name: "Hugfairy", 389 + url: "https://bsky.app/profile/hugfairy.bsky.social", 390 + category: "Services", 391 + subcategory: "AppViews", 392 + description: "Send a hug to someone on Bluesky", 393 + domain: "bsky.app", 394 + quality: 3, 395 + featured: false 396 + }, 397 + { 398 + name: "BlueNotify", 399 + url: "https://apps.apple.com/us/app/bluenotify/id6738239349", 400 + category: "Services", 401 + subcategory: "AppViews", 402 + description: "Post notifications for Bluesky", 403 + domain: "apple.com", 404 + quality: 4, 405 + featured: false 406 + }, 407 + { 408 + name: "ATFile", 409 + url: "https://github.com/ziodotsh/atfile", 410 + category: "Services", 411 + subcategory: "AppViews", 412 + description: "Share files on a PDS", 413 + domain: "github.com", 414 + quality: 3, 415 + featured: false 416 + }, 417 + { 418 + name: "Bluecast", 419 + url: "https://www.bluecast.app", 420 + category: "Services", 421 + subcategory: "AppViews", 422 + description: "Real-time audio streaming service", 423 + domain: "bluecast.app", 424 + quality: 4, 425 + featured: false 426 + }, 427 + { 428 + name: "Blue Place", 429 + url: "https://place.blue", 430 + category: "Services", 431 + subcategory: "AppViews", 432 + description: "r/place, but for Bluesky", 433 + domain: "place.blue", 434 + quality: 3, 435 + featured: false 436 + }, 437 + { 438 + name: "pastesphere", 439 + url: "https://pastesphere.link/", 440 + category: "Services", 441 + subcategory: "AppViews", 442 + description: "Paste-bin on the AT Protocol", 443 + domain: "pastesphere.link", 444 + quality: 3, 445 + featured: false 446 + }, 447 + { 448 + name: "Recipe Exchange", 449 + url: "https://recipe.exchange/", 450 + category: "Services", 451 + subcategory: "AppViews", 452 + description: "Share and discover recipes", 453 + domain: "recipe.exchange", 454 + quality: 4, 455 + featured: false 456 + }, 457 + { 458 + name: "skywatched", 459 + url: "https://skywatched.app/", 460 + category: "Services", 461 + subcategory: "AppViews", 462 + description: "Review and track movies", 463 + domain: "skywatched.app", 464 + quality: 4, 465 + featured: false 466 + }, 467 + { 468 + name: "Ruthub", 469 + url: "https://ruthub.com", 470 + category: "Services", 471 + subcategory: "AppViews", 472 + description: "Kanban on AT Proto", 473 + domain: "ruthub.com", 474 + quality: 3, 475 + featured: false 476 + }, 477 + { 478 + name: "dazzle.fm", 479 + url: "https://dazzle.fm/trends", 480 + category: "Services", 481 + subcategory: "AppViews", 482 + description: "What's happening on Bluesky", 483 + domain: "dazzle.fm", 484 + quality: 3, 485 + featured: false 486 + }, 111 487 112 488 // Data Management 113 489 { ··· 116 492 category: "Data", 117 493 subcategory: "Management", 118 494 description: "Bulk retroactive thread gating", 495 + domain: "kelinci.net", 119 496 quality: 3, 120 497 featured: false 121 498 }, ··· 125 502 category: "Data", 126 503 subcategory: "Management", 127 504 description: "Auto-delete old skeets", 505 + domain: "p8.lu", 506 + quality: 4, 507 + featured: false 508 + }, 509 + { 510 + name: "Skeetgen", 511 + url: "https://mary-ext.github.io/skeetgen/", 512 + category: "Data", 513 + subcategory: "Management", 514 + description: "Generate an easily viewable archive of your posts", 515 + domain: "github.io", 516 + quality: 4, 517 + featured: false 518 + }, 519 + { 520 + name: "Profile Cleaner", 521 + url: "https://bsky.jazco.dev/cleanup", 522 + category: "Data", 523 + subcategory: "Management", 524 + description: "Clean up your Bluesky profile", 525 + domain: "jazco.dev", 526 + quality: 3, 527 + featured: false 528 + }, 529 + { 530 + name: "Backup Tool", 531 + url: "https://observablehq.com/@aendra/bluesky-backup-tool", 532 + category: "Data", 533 + subcategory: "Management", 534 + description: "Back up your Bluesky data", 535 + domain: "observablehq.com", 536 + quality: 3, 537 + featured: false 538 + }, 539 + { 540 + name: "Tweet Deleter", 541 + url: "http://tweetdeleter.com", 542 + category: "Data", 543 + subcategory: "Management", 544 + description: "Delete your old tweets", 545 + domain: "tweetdeleter.com", 546 + quality: 3, 547 + featured: false 548 + }, 549 + { 550 + name: "redact.dev", 551 + url: "http://redact.dev", 552 + category: "Data", 553 + subcategory: "Management", 554 + description: "Delete posts from various platforms", 555 + domain: "redact.dev", 556 + quality: 3, 557 + featured: false 558 + }, 559 + { 560 + name: "Blockparty", 561 + url: "http://blockpartyapp.com", 562 + category: "Data", 563 + subcategory: "Management", 564 + description: "Manage blocks across platforms", 565 + domain: "blockpartyapp.com", 566 + quality: 3, 567 + featured: false 568 + }, 569 + { 570 + name: "Porto", 571 + url: "https://chromewebstore.google.com/detail/porto-import-your-tweets/ckilhjdflnaakopknngigiggfpnjaaop", 572 + category: "Data", 573 + subcategory: "Management", 574 + description: "Import your tweets to Bluesky", 575 + domain: "google.com", 576 + quality: 4, 577 + featured: false 578 + }, 579 + { 580 + name: "BlueArk", 581 + url: "https://blueark.app", 582 + category: "Data", 583 + subcategory: "Management", 584 + description: "Move your tweets to Bluesky", 585 + domain: "blueark.app", 128 586 quality: 4, 129 587 featured: false 130 588 }, ··· 136 594 category: "Network", 137 595 subcategory: "Management", 138 596 description: "Find and analyze your network connections", 597 + domain: "theo.io", 139 598 quality: 4, 140 599 featured: true 141 600 }, ··· 145 604 category: "Network", 146 605 subcategory: "Management", 147 606 description: "Track and manage who you're following", 607 + domain: "cam.fyi", 148 608 quality: 4, 149 609 featured: true 150 610 }, 611 + { 612 + name: "Sky Follower Bridge", 613 + url: "https://chromewebstore.google.com/detail/sky-follower-bridge/behhbpbpmailcnfbjagknjngnfdojpko/", 614 + category: "Network", 615 + subcategory: "Management", 616 + description: "Find your Twitter follows", 617 + domain: "google.com", 618 + quality: 4, 619 + featured: false 620 + }, 621 + { 622 + name: "StarterPacks.net", 623 + url: "https://www.starterpacks.net", 624 + category: "Network", 625 + subcategory: "Management", 626 + description: "Explore starter packs", 627 + domain: "starterpacks.net", 628 + quality: 4, 629 + featured: false 630 + }, 631 + { 632 + name: "Follower Explorer", 633 + url: "https://bluesky-followers.advaith.io", 634 + category: "Network", 635 + subcategory: "Management", 636 + description: "Explore your followers", 637 + domain: "advaith.io", 638 + quality: 3, 639 + featured: false 640 + }, 641 + { 642 + name: "cleanfollow", 643 + url: "https://cleanfollow-bsky.pages.dev", 644 + category: "Network", 645 + subcategory: "Management", 646 + description: "Select inactive or blocked accounts to unfollow", 647 + domain: "pages.dev", 648 + quality: 3, 649 + featured: false 650 + }, 651 + { 652 + name: "Bluesky Follower Info", 653 + url: "https://chromewebstore.google.com/detail/bluesky-follower-info/fokpfcfpgdlmnbjajbdeofkemfblbnbh", 654 + category: "Network", 655 + subcategory: "Management", 656 + description: "Chrome extension for follower info", 657 + domain: "google.com", 658 + quality: 3, 659 + featured: false 660 + }, 661 + { 662 + name: "unfollow.blue", 663 + url: "https://unfollow.blue/", 664 + category: "Network", 665 + subcategory: "Management", 666 + description: "Track unfollows and follows", 667 + domain: "unfollow.blue", 668 + quality: 3, 669 + featured: false 670 + }, 671 + { 672 + name: "Blockenheimer", 673 + url: "https://blockenheimer.click/", 674 + category: "Network", 675 + subcategory: "Management", 676 + description: "Block large amounts of accounts", 677 + domain: "blockenheimer.click", 678 + quality: 3, 679 + featured: false 680 + }, 681 + { 682 + name: "Convert Starter Pack to List", 683 + url: "https://nws-bot.us/bskyStarterPack.php", 684 + category: "Network", 685 + subcategory: "Management", 686 + description: "Convert starter packs to lists", 687 + domain: "nws-bot.us", 688 + quality: 3, 689 + featured: false 690 + }, 691 + { 692 + name: "List Copier", 693 + url: "https://bsky.cam.fyi/lists", 694 + category: "Network", 695 + subcategory: "Management", 696 + description: "Copy lists between accounts", 697 + domain: "cam.fyi", 698 + quality: 3, 699 + featured: false 700 + }, 701 + { 702 + name: "listfluff", 703 + url: "https://github.com/mollypup/listfluff?tab=readme-ov-file", 704 + category: "Network", 705 + subcategory: "Management", 706 + description: "Add and remove users from Bluesky lists", 707 + domain: "github.com", 708 + quality: 3, 709 + featured: false 710 + }, 711 + { 712 + name: "Which Pack", 713 + url: "https://whichpack.com/", 714 + category: "Network", 715 + subcategory: "Management", 716 + description: "See what starterpacks you're in", 717 + domain: "whichpack.com", 718 + quality: 3, 719 + featured: false 720 + }, 721 + { 722 + name: "AT Orbital Laser", 723 + url: "https://at-orbital-laser.aesthr.com/", 724 + category: "Network", 725 + subcategory: "Management", 726 + description: "Block a user and their followers", 727 + domain: "aesthr.com", 728 + quality: 3, 729 + featured: false 730 + }, 151 731 152 732 // Alternative Clients 153 733 { ··· 156 736 category: "Clients", 157 737 subcategory: "Alternative", 158 738 description: "TweetDeck for Bluesky", 739 + domain: "deck.blue", 159 740 quality: 4, 160 741 featured: false 161 742 }, ··· 165 746 category: "Clients", 166 747 subcategory: "Alternative", 167 748 description: "Alternative mobile client", 749 + domain: "graysky.app", 168 750 quality: 5, 169 751 featured: false 170 752 }, 753 + { 754 + name: "Skeets App", 755 + url: "https://www.skeetsapp.com", 756 + category: "Clients", 757 + subcategory: "Alternative", 758 + description: "Third-party Bluesky client", 759 + domain: "skeetsapp.com", 760 + quality: 4, 761 + featured: false 762 + }, 763 + { 764 + name: "Ouranos", 765 + url: "https://useouranos.app/", 766 + category: "Clients", 767 + subcategory: "Alternative", 768 + description: "Alternative Bluesky client", 769 + domain: "useouranos.app", 770 + quality: 4, 771 + featured: false 772 + }, 773 + { 774 + name: "Butterfly", 775 + url: "https://apps.apple.com/us/app/butterfly-for-bluesky/id6738070758", 776 + category: "Clients", 777 + subcategory: "Alternative", 778 + description: "Bluesky for Apple Watch", 779 + domain: "apple.com", 780 + quality: 3, 781 + featured: false 782 + }, 783 + { 784 + name: "Ucho-ten", 785 + url: "https://app.ucho-ten.net/", 786 + category: "Clients", 787 + subcategory: "Alternative", 788 + description: "Alternative Bluesky client", 789 + domain: "ucho-ten.net", 790 + quality: 4, 791 + featured: false 792 + }, 793 + { 794 + name: "Swablu", 795 + url: "https://swablu.pages.dev/#/login", 796 + category: "Clients", 797 + subcategory: "Alternative", 798 + description: "Web-based Bluesky client", 799 + domain: "pages.dev", 800 + quality: 3, 801 + featured: false 802 + }, 803 + { 804 + name: "Bluejeans", 805 + url: "https://bluejeans.app/", 806 + category: "Clients", 807 + subcategory: "Alternative", 808 + description: "Alternative Bluesky client", 809 + domain: "bluejeans.app", 810 + quality: 3, 811 + featured: false 812 + }, 171 813 172 814 // Labelers & Moderation 173 815 { ··· 176 818 category: "Moderation", 177 819 subcategory: "Labelers", 178 820 description: "Labels political content", 821 + domain: "bsky.app", 179 822 quality: 4, 180 823 featured: true 181 824 }, ··· 185 828 category: "Moderation", 186 829 subcategory: "Labelers", 187 830 description: "Adds pronoun information to profiles", 831 + domain: "bsky.app", 188 832 quality: 4, 189 833 featured: true 190 834 }, 835 + { 836 + name: "Labeler List", 837 + url: "https://blue.mackuba.eu/labellers/", 838 + category: "Moderation", 839 + subcategory: "Labelers", 840 + description: "Directory of available labelers", 841 + domain: "mackuba.eu", 842 + quality: 4, 843 + featured: false 844 + }, 845 + { 846 + name: "Label Scanner", 847 + url: "https://blue.mackuba.eu/scanner/", 848 + category: "Moderation", 849 + subcategory: "Labelers", 850 + description: "See what labels are on your account", 851 + domain: "mackuba.eu", 852 + quality: 4, 853 + featured: false 854 + }, 855 + { 856 + name: "Identity Decentralisation", 857 + url: "https://bsky.app/profile/decentralise.goeo.lol", 858 + category: "Moderation", 859 + subcategory: "Labelers", 860 + description: "Labeler for decentralization identification", 861 + domain: "bsky.app", 862 + quality: 3, 863 + featured: false 864 + }, 865 + { 866 + name: "Official Moderation", 867 + url: "https://bsky.app/profile/moderation.bsky.app", 868 + category: "Moderation", 869 + subcategory: "Labelers", 870 + description: "Official Bluesky moderation account", 871 + domain: "bsky.app", 872 + quality: 5, 873 + featured: false 874 + }, 875 + { 876 + name: "Profile Records", 877 + url: "https://bsky.app/profile/profile-labels.bossett.social", 878 + category: "Moderation", 879 + subcategory: "Labelers", 880 + description: "Profile record labeler", 881 + domain: "bsky.app", 882 + quality: 3, 883 + featured: false 884 + }, 885 + { 886 + name: "Skywatch", 887 + url: "https://bsky.app/profile/skywatch.blue", 888 + category: "Moderation", 889 + subcategory: "Labelers", 890 + description: "Multipurpose labeler", 891 + domain: "bsky.app", 892 + quality: 4, 893 + featured: false 894 + }, 895 + { 896 + name: "Khronos", 897 + url: "https://bsky.app/profile/khronos.world", 898 + category: "Moderation", 899 + subcategory: "Labelers", 900 + description: "Time zone labels", 901 + domain: "bsky.app", 902 + quality: 3, 903 + featured: false 904 + }, 905 + { 906 + name: "Blacksky", 907 + url: "https://bsky.app/profile/blacksky.app", 908 + category: "Moderation", 909 + subcategory: "Labelers", 910 + description: "Content moderation labeler", 911 + domain: "bsky.app", 912 + quality: 3, 913 + featured: false 914 + }, 915 + { 916 + name: "US Gov Contributions", 917 + url: "https://bsky.app/profile/us-gov-funding.bsky.social", 918 + category: "Moderation", 919 + subcategory: "Labelers", 920 + description: "Labels users with government funding", 921 + domain: "bsky.app", 922 + quality: 3, 923 + featured: false 924 + }, 925 + { 926 + name: "Screenshots", 927 + url: "https://bsky.app/profile/xblock.aendra.dev", 928 + category: "Moderation", 929 + subcategory: "Labelers", 930 + description: "Labels screenshots", 931 + domain: "bsky.app", 932 + quality: 3, 933 + featured: false 934 + }, 935 + { 936 + name: "AI Imagery", 937 + url: "https://bsky.app/profile/aimod.social", 938 + category: "Moderation", 939 + subcategory: "Labelers", 940 + description: "Labels AI-generated imagery", 941 + domain: "bsky.app", 942 + quality: 4, 943 + featured: false 944 + }, 945 + { 946 + name: "Content Creator Labels", 947 + url: "https://bsky.app/profile/creatorlabeler.bsky.social", 948 + category: "Moderation", 949 + subcategory: "Labelers", 950 + description: "Labels content creators", 951 + domain: "bsky.app", 952 + quality: 3, 953 + featured: false 954 + }, 955 + { 956 + name: "Shiny Posts", 957 + url: "https://bsky.app/profile/shinyposts.awoo.blue", 958 + category: "Moderation", 959 + subcategory: "Labelers", 960 + description: "Labels visually distinct posts", 961 + domain: "bsky.app", 962 + quality: 3, 963 + featured: false 964 + }, 965 + { 966 + name: "Mushroom Server Labels", 967 + url: "https://bsky.app/profile/mushroom-labeler.bsky.social", 968 + category: "Moderation", 969 + subcategory: "Labelers", 970 + description: "Labels mushroom content", 971 + domain: "bsky.app", 972 + quality: 3, 973 + featured: false 974 + }, 975 + { 976 + name: "Nations", 977 + url: "https://bsky.app/profile/kickflip.renahlee.com", 978 + category: "Moderation", 979 + subcategory: "Labelers", 980 + description: "Labels users by country/nationality", 981 + domain: "bsky.app", 982 + quality: 3, 983 + featured: false 984 + }, 191 985 192 986 // Feeds & Discovery 193 987 { 988 + name: "Graze", 989 + url: "https://www.graze.social/", 990 + category: "Feeds", 991 + subcategory: "Feed Tools", 992 + description: "No-Code feed creator", 993 + domain: "graze.social", 994 + quality: 5, 995 + featured: true 996 + }, 997 + { 998 + name: "goodfeeds.com", 999 + url: "https://goodfeeds.co/all?p=1", 1000 + category: "Feeds", 1001 + subcategory: "Feed Tools", 1002 + description: "Discover feeds", 1003 + domain: "goodfeeds.co", 1004 + quality: 4, 1005 + featured: false 1006 + }, 1007 + { 1008 + name: "Bluefeed", 1009 + url: "https://www.bluefeed.app", 1010 + category: "Feeds", 1011 + subcategory: "Feed Tools", 1012 + description: "Discover feeds", 1013 + domain: "bluefeed.app", 1014 + quality: 4, 1015 + featured: false 1016 + }, 1017 + { 194 1018 name: "Quiet Posters", 195 1019 url: "https://bsky.app/profile/did:plc:vpkhqolt662uhesyj6nxm7ys/feed/infreq", 196 1020 category: "Feeds", 197 1021 subcategory: "Discovery", 198 1022 description: "Feed of less frequent posters", 1023 + domain: "bsky.app", 1024 + quality: 3, 1025 + featured: false 1026 + }, 1027 + { 1028 + name: "Popular with Friends", 1029 + url: "https://bsky.app/profile/bsky.app/feed/with-friends", 1030 + category: "Feeds", 1031 + subcategory: "Discovery", 1032 + description: "Posts popular with your friends", 1033 + domain: "bsky.app", 1034 + quality: 4, 1035 + featured: false 1036 + }, 1037 + { 1038 + name: "Best of Friends", 1039 + url: "https://bsky.app/profile/bsky.app/feed/best-of-follows", 1040 + category: "Feeds", 1041 + subcategory: "Discovery", 1042 + description: "Best posts from who you follow", 1043 + domain: "bsky.app", 1044 + quality: 4, 1045 + featured: false 1046 + }, 1047 + { 1048 + name: "Trending Links", 1049 + url: "https://bsky.app/profile/why.bsky.team/feed/links", 1050 + category: "Feeds", 1051 + subcategory: "Discovery", 1052 + description: "Popular links being shared", 1053 + domain: "bsky.app", 1054 + quality: 4, 1055 + featured: false 1056 + }, 1057 + { 1058 + name: "Only Posts", 1059 + url: "https://bsky.app/profile/did:plc:tenurhgjptubkk5zf5qhi3og/feed/only-posts", 1060 + category: "Feeds", 1061 + subcategory: "Discovery", 1062 + description: "No reposts or replies", 1063 + domain: "bsky.app", 1064 + quality: 3, 1065 + featured: false 1066 + }, 1067 + { 1068 + name: "Mentions Only", 1069 + url: "https://bsky.app/profile/flicknow.xyz/feed/mentions", 1070 + category: "Feeds", 1071 + subcategory: "Discovery", 1072 + description: "See only mentions", 1073 + domain: "bsky.app", 1074 + quality: 3, 1075 + featured: false 1076 + }, 1077 + { 1078 + name: "My Misses", 1079 + url: "https://bsky.app/profile/goeo.lol/feed/misses", 1080 + category: "Feeds", 1081 + subcategory: "Discovery", 1082 + description: "See your unliked posts", 1083 + domain: "bsky.app", 1084 + quality: 3, 1085 + featured: false 1086 + }, 1087 + { 1088 + name: "My Bangers", 1089 + url: "https://bsky.app/profile/jaz.bsky.social/feed/bangers", 1090 + category: "Feeds", 1091 + subcategory: "Discovery", 1092 + description: "See your most liked posts", 1093 + domain: "bsky.app", 199 1094 quality: 3, 200 1095 featured: false 201 1096 }, ··· 207 1102 category: "Visualizations", 208 1103 subcategory: "Firehose", 209 1104 description: "Live visualization of the firehose", 1105 + domain: "flikq.dev", 210 1106 quality: 3, 211 1107 featured: false 212 1108 }, ··· 216 1112 category: "Visualizations", 217 1113 subcategory: "Firehose", 218 1114 description: "Glimpses of deleted posts", 1115 + domain: "bad-example.com", 219 1116 quality: 3, 220 1117 featured: true 221 1118 }, 1119 + { 1120 + name: "Swearsky", 1121 + url: "http://swearsky.bagpuss.org", 1122 + category: "Visualizations", 1123 + subcategory: "Firehose", 1124 + description: "Visualize swearing on Bluesky", 1125 + domain: "bagpuss.org", 1126 + quality: 3, 1127 + featured: false 1128 + }, 1129 + { 1130 + name: "3D Firehose", 1131 + url: "https://firehose3d.theo.io", 1132 + category: "Visualizations", 1133 + subcategory: "Firehose", 1134 + description: "3D visualization of Bluesky posts", 1135 + domain: "theo.io", 1136 + quality: 3, 1137 + featured: false 1138 + }, 1139 + { 1140 + name: "Firesky", 1141 + url: "https://firesky.tv", 1142 + category: "Visualizations", 1143 + subcategory: "Firehose", 1144 + description: "Visualize the Bluesky firehose", 1145 + domain: "firesky.tv", 1146 + quality: 3, 1147 + featured: false 1148 + }, 1149 + { 1150 + name: "ATProto Firehose Event Counter", 1151 + url: "https://atproto.netlify.app", 1152 + category: "Visualizations", 1153 + subcategory: "Firehose", 1154 + description: "Count events in the firehose", 1155 + domain: "netlify.app", 1156 + quality: 3, 1157 + featured: false 1158 + }, 1159 + { 1160 + name: "Matrix Style Visualization", 1161 + url: "https://simone.computer/bluerain/", 1162 + category: "Visualizations", 1163 + subcategory: "Firehose", 1164 + description: "Matrix-inspired visualization", 1165 + domain: "simone.computer", 1166 + quality: 3, 1167 + featured: false 1168 + }, 1169 + { 1170 + name: "Spaceship Firehose Game", 1171 + url: "https://spaceshipfirehose.vercel.app/", 1172 + category: "Visualizations", 1173 + subcategory: "Firehose", 1174 + description: "Game powered by Bluesky firehose", 1175 + domain: "vercel.app", 1176 + quality: 3, 1177 + featured: false 1178 + }, 1179 + { 1180 + name: "Live Word Cloud", 1181 + url: "https://flo-bit.dev/bluesky-visualizers/wordcloud", 1182 + category: "Visualizations", 1183 + subcategory: "Firehose", 1184 + description: "Real-time word cloud of posts", 1185 + domain: "flo-bit.dev", 1186 + quality: 3, 1187 + featured: false 1188 + }, 1189 + { 1190 + name: "Trending Hashtags", 1191 + url: "https://flo-bit.dev/bluesky-trending/", 1192 + category: "Visualizations", 1193 + subcategory: "Firehose", 1194 + description: "See trending hashtags", 1195 + domain: "flo-bit.dev", 1196 + quality: 3, 1197 + featured: false 1198 + }, 1199 + { 1200 + name: "Emotions Analysis", 1201 + url: "https://flo-bit.dev/bluesky-visualizers/emotions", 1202 + category: "Visualizations", 1203 + subcategory: "Firehose", 1204 + description: "Analyze emotions in posts", 1205 + domain: "flo-bit.dev", 1206 + quality: 3, 1207 + featured: false 1208 + }, 1209 + { 1210 + name: "Imagehose", 1211 + url: "https://imagehose.net/", 1212 + category: "Visualizations", 1213 + subcategory: "Firehose", 1214 + description: "Stream of images from Bluesky", 1215 + domain: "imagehose.net", 1216 + quality: 3, 1217 + featured: false 1218 + }, 1219 + { 1220 + name: "Colors of Bluesky", 1221 + url: "https://www.bewitched.com/demo/rainbowsky/", 1222 + category: "Visualizations", 1223 + subcategory: "Firehose", 1224 + description: "Color visualization of posts", 1225 + domain: "bewitched.com", 1226 + quality: 3, 1227 + featured: false 1228 + }, 222 1229 223 1230 // Developer Tools 224 1231 { ··· 227 1234 category: "Development", 228 1235 subcategory: "Tools", 229 1236 description: "Browse AtProto repositories", 1237 + domain: "pdsls.dev", 230 1238 quality: 5, 231 1239 featured: true 232 1240 }, ··· 236 1244 category: "Development", 237 1245 subcategory: "Tools", 238 1246 description: "Libraries & SDKs for the AT Protocol", 1247 + domain: "sdk.blue", 239 1248 quality: 4, 240 1249 featured: false 241 1250 }, 1251 + { 1252 + name: "atp.tools", 1253 + url: "https://atp.tools/", 1254 + category: "Development", 1255 + subcategory: "Tools", 1256 + description: "Developer tools for AT Protocol", 1257 + domain: "atp.tools", 1258 + quality: 4, 1259 + featured: false 1260 + }, 1261 + { 1262 + name: "Resolve a Bluesky Handle", 1263 + url: "https://internect.info", 1264 + category: "Development", 1265 + subcategory: "Tools", 1266 + description: "Handle resolution tool", 1267 + domain: "internect.info", 1268 + quality: 3, 1269 + featured: false 1270 + }, 1271 + { 1272 + name: "Boat", 1273 + url: "https://boat.kelinci.net/", 1274 + category: "Development", 1275 + subcategory: "Tools", 1276 + description: "Various technical tools", 1277 + domain: "kelinci.net", 1278 + quality: 3, 1279 + featured: false 1280 + }, 1281 + { 1282 + name: "blue.badge", 1283 + url: "https://badge.blue", 1284 + category: "Development", 1285 + subcategory: "Tools", 1286 + description: "Define, issue, and verify badges", 1287 + domain: "badge.blue", 1288 + quality: 3, 1289 + featured: false 1290 + }, 1291 + { 1292 + name: "browser.blue", 1293 + url: "https://browser.blue/types", 1294 + category: "Development", 1295 + subcategory: "Tools", 1296 + description: "Browse AT Protocol types", 1297 + domain: "browser.blue", 1298 + quality: 3, 1299 + featured: false 1300 + }, 1301 + { 1302 + name: "SkyTools", 1303 + url: "https://skytools.anon5r.com/profile", 1304 + category: "Development", 1305 + subcategory: "Tools", 1306 + description: "Various developer tools", 1307 + domain: "anon5r.com", 1308 + quality: 3, 1309 + featured: false 1310 + }, 1311 + { 1312 + name: "Lexicon Community", 1313 + url: "https://github.com/lexicon-community", 1314 + category: "Development", 1315 + subcategory: "Tools", 1316 + description: "Community-made lexicons", 1317 + domain: "github.com", 1318 + quality: 3, 1319 + featured: false 1320 + }, 1321 + { 1322 + name: "atproto-did-web", 1323 + url: "https://atproto-did-web.lukeacl.com/", 1324 + category: "Development", 1325 + subcategory: "Tools", 1326 + description: "DID web tools for AT Protocol", 1327 + domain: "lukeacl.com", 1328 + quality: 3, 1329 + featured: false 1330 + }, 1331 + { 1332 + name: "Manual", 1333 + url: "https://manual.renahlee.com/", 1334 + category: "Development", 1335 + subcategory: "Tools", 1336 + description: "Set a non-default PLC key", 1337 + domain: "renahlee.com", 1338 + quality: 3, 1339 + featured: false 1340 + }, 1341 + { 1342 + name: "Skeetbeaver", 1343 + url: "https://skeetbeaver.pages.dev/", 1344 + category: "Development", 1345 + subcategory: "Tools", 1346 + description: "Assorted tools for retrieving data", 1347 + domain: "pages.dev", 1348 + quality: 3, 1349 + featured: false 1350 + }, 1351 + { 1352 + name: "Bsky Debug Page", 1353 + url: "https://bsky-debug.app/handle", 1354 + category: "Development", 1355 + subcategory: "Tools", 1356 + description: "Debug Bluesky handles and profiles", 1357 + domain: "bsky-debug.app", 1358 + quality: 3, 1359 + featured: false 1360 + }, 1361 + { 1362 + name: "Skyware", 1363 + url: "https://skyware.js.org", 1364 + category: "Development", 1365 + subcategory: "Tools", 1366 + description: "Package collection for developers", 1367 + domain: "js.org", 1368 + quality: 3, 1369 + featured: false 1370 + }, 1371 + { 1372 + name: "Atcute", 1373 + url: "https://github.com/mary-ext/atcute", 1374 + category: "Development", 1375 + subcategory: "Tools", 1376 + description: "Lightweight TypeScript packages for AT Protocol", 1377 + domain: "github.com", 1378 + quality: 4, 1379 + featured: false 1380 + }, 1381 + { 1382 + name: "bluesky-embed", 1383 + url: "https://github.com/mary-ext/bluesky-embed", 1384 + category: "Development", 1385 + subcategory: "Tools", 1386 + description: "Custom element for embedding Bluesky posts", 1387 + domain: "github.com", 1388 + quality: 4, 1389 + featured: false 1390 + }, 1391 + { 1392 + name: "Clearsky API", 1393 + url: "https://github.com/ClearskyApp06/clearskyservices/blob/main/api.md", 1394 + category: "Development", 1395 + subcategory: "Tools", 1396 + description: "API for ClearSky services", 1397 + domain: "github.com", 1398 + quality: 3, 1399 + featured: false 1400 + }, 1401 + { 1402 + name: "Hopper", 1403 + url: "https://hopper.at/", 1404 + category: "Development", 1405 + subcategory: "Tools", 1406 + description: "AT-URI redirection tool", 1407 + domain: "hopper.at", 1408 + quality: 3, 1409 + featured: false 1410 + }, 1411 + { 1412 + name: "atproto-scraping", 1413 + url: "https://github.com/mary-ext/atproto-scraping", 1414 + category: "Development", 1415 + subcategory: "Tools", 1416 + description: "Scraping tools for AT Protocol", 1417 + domain: "github.com", 1418 + quality: 3, 1419 + featured: false 1420 + }, 1421 + { 1422 + name: "TID converter", 1423 + url: "https://mary.my.id/tools/tid-converter", 1424 + category: "Development", 1425 + subcategory: "Tools", 1426 + description: "Convert between TIDs and dates", 1427 + domain: "mary.my.id", 1428 + quality: 3, 1429 + featured: false 1430 + }, 1431 + { 1432 + name: "Weather Vane", 1433 + url: "https://verify.aviary.domains/", 1434 + category: "Development", 1435 + subcategory: "Tools", 1436 + description: "Domain verification tool", 1437 + domain: "aviary.domains", 1438 + quality: 3, 1439 + featured: false 1440 + }, 1441 + { 1442 + name: "TID clock", 1443 + url: "https://retr0.id/stuff/atclock/", 1444 + category: "Development", 1445 + subcategory: "Tools", 1446 + description: "Visual TID clock", 1447 + domain: "retr0.id", 1448 + quality: 3, 1449 + featured: false 1450 + }, 1451 + { 1452 + name: "handles.net", 1453 + url: "https://handles.net/", 1454 + category: "Development", 1455 + subcategory: "Tools", 1456 + description: "Manage Bluesky handles for your community", 1457 + domain: "handles.net", 1458 + quality: 4, 1459 + featured: false 1460 + }, 1461 + { 1462 + name: "Lexidex", 1463 + url: "https://lexidex.bsky.dev/", 1464 + category: "Development", 1465 + subcategory: "Tools", 1466 + description: "Catalog of lexicons", 1467 + domain: "bsky.dev", 1468 + quality: 3, 1469 + featured: false 1470 + }, 242 1471 243 1472 // Guides & Documentation 244 1473 { ··· 247 1476 category: "Guides", 248 1477 subcategory: "Documentation", 249 1478 description: "How to verify your Bluesky account", 1479 + domain: "bsky.social", 250 1480 quality: 4, 251 1481 featured: false 252 1482 }, ··· 256 1486 category: "Guides", 257 1487 subcategory: "Documentation", 258 1488 description: "Comprehensive Bluesky guide", 1489 + domain: "mackuba.eu", 259 1490 quality: 5, 260 1491 featured: false 261 1492 }, 1493 + { 1494 + name: "Advanced Search Guide", 1495 + url: "https://bsky.social/about/blog/05-31-2024-search", 1496 + category: "Guides", 1497 + subcategory: "Documentation", 1498 + description: "Guide to using advanced search", 1499 + domain: "bsky.social", 1500 + quality: 4, 1501 + featured: false 1502 + }, 1503 + { 1504 + name: "Run your own PDS Server", 1505 + url: "https://www.youtube.com/watch?v=7-VJvf39xVE&t=4s", 1506 + category: "Guides", 1507 + subcategory: "Documentation", 1508 + description: "How to run your own Bluesky PDS Server", 1509 + domain: "youtube.com", 1510 + quality: 4, 1511 + featured: false 1512 + }, 262 1513 263 1514 // Miscellaneous 264 1515 { ··· 267 1518 category: "Misc", 268 1519 subcategory: "Tools", 269 1520 description: "Create and organize threads", 1521 + domain: "pages.dev", 270 1522 quality: 3, 271 1523 featured: false 272 1524 }, ··· 276 1528 category: "Misc", 277 1529 subcategory: "Tools", 278 1530 description: "Share threads with people without an account", 1531 + domain: "skyview.social", 279 1532 quality: 4, 280 1533 featured: false 281 1534 }, ··· 285 1538 category: "Misc", 286 1539 subcategory: "Tools", 287 1540 description: "Video downloader", 1541 + domain: "down.blue", 1542 + quality: 3, 1543 + featured: false 1544 + }, 1545 + { 1546 + name: "iOS Shortcuts Collection", 1547 + url: "https://matthewcassinelli.com/shortcuts/folders/bluesky/", 1548 + category: "Misc", 1549 + subcategory: "Tools", 1550 + description: "Useful iOS shortcuts for Bluesky", 1551 + domain: "matthewcassinelli.com", 1552 + quality: 3, 1553 + featured: false 1554 + }, 1555 + { 1556 + name: "Bookmarks/Drafts Workaround", 1557 + url: "https://bsky.app/profile/dame.bsky.social/post/3lb5wrehvdc2g", 1558 + category: "Misc", 1559 + subcategory: "Tools", 1560 + description: "Workaround for saving bookmarks/drafts", 1561 + domain: "bsky.app", 1562 + quality: 3, 1563 + featured: false 1564 + }, 1565 + { 1566 + name: "cobalt.tools", 1567 + url: "https://cobalt.tools", 1568 + category: "Misc", 1569 + subcategory: "Tools", 1570 + description: "Media saver", 1571 + domain: "cobalt.tools", 1572 + quality: 3, 1573 + featured: false 1574 + }, 1575 + { 1576 + name: "Social Profile Widget Generator", 1577 + url: "https://bsky-widget.srbh.dev", 1578 + category: "Misc", 1579 + subcategory: "Tools", 1580 + description: "Generate profile widgets", 1581 + domain: "srbh.dev", 1582 + quality: 3, 1583 + featured: false 1584 + }, 1585 + { 1586 + name: "Bluesky Lore", 1587 + url: "https://bsky.app/profile/jay.bsky.team/post/3lbd2eaura22r", 1588 + category: "Misc", 1589 + subcategory: "Tools", 1590 + description: "Bluesky lore, as told by Jay", 1591 + domain: "bsky.app", 1592 + quality: 3, 1593 + featured: false 1594 + }, 1595 + { 1596 + name: "The Fediverse Report", 1597 + url: "https://fediversereport.com", 1598 + category: "Misc", 1599 + subcategory: "Tools", 1600 + description: "Bluesky and ATmosphere newsletter", 1601 + domain: "fediversereport.com", 288 1602 quality: 3, 289 1603 featured: false 290 1604 } ··· 318 1632 // Filter by search query 319 1633 const searchMatch = 320 1634 resource.name.toLowerCase().includes(searchQuery.toLowerCase()) || 321 - resource.description.toLowerCase().includes(searchQuery.toLowerCase()); 1635 + resource.description.toLowerCase().includes(searchQuery.toLowerCase()) || 1636 + (resource.domain && resource.domain.toLowerCase().includes(searchQuery.toLowerCase())); 322 1637 323 1638 // Filter by quality 324 1639 const qualityMatch = ··· 336 1651 return resourcesWithUTM.filter(resource => resource.featured); 337 1652 }, [resourcesWithUTM]); 338 1653 1654 + // Should show featured section only when All category is selected 1655 + const shouldShowFeatured = activeCategory === 'All'; 1656 + 339 1657 // Simulate loading data 340 1658 useEffect(() => { 341 1659 // Simulate API fetch with a timeout ··· 391 1709 </div> 392 1710 393 1711 <div className="filter-options"> 394 - <div className="category-filters"> 395 - {categories.map(category => ( 396 - <button 397 - key={category} 398 - className={`category-filter ${activeCategory === category ? 'active' : ''}`} 399 - onClick={() => setActiveCategory(category)} 400 - > 401 - {category} 402 - </button> 403 - ))} 1712 + <div className="category-filters-container"> 1713 + <div className="category-filters"> 1714 + {categories.map(category => ( 1715 + <button 1716 + key={category} 1717 + className={`category-filter ${activeCategory === category ? 'active' : ''}`} 1718 + onClick={() => setActiveCategory(category)} 1719 + > 1720 + {categoryEmojis[category]} {category} 1721 + </button> 1722 + ))} 1723 + </div> 404 1724 </div> 405 1725 406 1726 <div className="quality-filter"> ··· 418 1738 </div> 419 1739 </div> 420 1740 421 - {featuredResources.length > 0 && ( 1741 + {shouldShowFeatured && featuredResources.length > 0 && ( 422 1742 <div className="featured-section"> 423 1743 <h2>Featured Resources</h2> 1744 + <p className="featured-description">Hand-selected tools that we love and use regularly. These are not sponsored or paid placements.</p> 424 1745 <div className="resources-grid"> 425 1746 {featuredResources.map((resource, index) => ( 426 1747 <ResourceCard key={`featured-${index}`} resource={resource} /> ··· 430 1751 )} 431 1752 432 1753 <div className="all-resources-section"> 433 - <h2>{activeCategory === 'All' ? 'All Resources' : activeCategory}</h2> 1754 + <h2>{activeCategory === 'All' ? 'All Resources' : `${categoryEmojis[activeCategory]} ${activeCategory} Resources`}</h2> 434 1755 {filteredResources.length > 0 ? ( 435 1756 <div className="resources-grid"> 436 1757 {filteredResources.map((resource, index) => ( ··· 479 1800 <div className="resource-content"> 480 1801 <h3 className="resource-name">{resource.name}</h3> 481 1802 <p className="resource-description">{resource.description}</p> 1803 + <p className="resource-domain">{resource.domain}</p> 482 1804 <div className="resource-meta"> 483 1805 <span className="resource-category">{resource.category}</span> 484 1806 <div className="resource-quality">