browse the protocol like its 2008 ibex.desertthunder.dev
ubuntu atproto svelte
7

Configure Feed

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

feat: namespaced collection icons

Owais Jamil (Jun 17, 2026, 12:35 AM -0500) 97213c64 e96670e6

+84 -18
+5
.changeset/four-schools-sit.md
··· 1 + --- 2 + 'intrepid-ibex': patch 3 + --- 4 + 5 + icon overrides via namespaces
+19
src/lib/atproto/collection-icons.test.ts
··· 1 + import { describe, expect, it } from 'vitest'; 2 + 3 + import { appLabelForCollection, collectionIconMatch } from './collection-icons'; 4 + 5 + describe('collection icon registry', () => { 6 + it('maps chat.bsky collections to the Bluesky app icon', () => { 7 + expect(collectionIconMatch('chat.bsky.convo.defs')?.icon).toBe('/atmologos/color/bluesky.svg'); 8 + expect(appLabelForCollection('chat.bsky.convo.defs')).toBe('Bluesky'); 9 + }); 10 + 11 + it('maps explicit namespace icons to their static namespace path', () => { 12 + expect(collectionIconMatch('at.inlay.record.comment')?.icon).toBe('/icons/namespaces/at/inlay/icon.svg'); 13 + expect(appLabelForCollection('at.inlay.record.comment')).toBe('Inlay'); 14 + }); 15 + 16 + it('uses the most specific matching prefix', () => { 17 + expect(collectionIconMatch('app.bsky.feed.post')?.icon).toBe('/atmologos/color/bluesky.svg'); 18 + }); 19 + });
+33 -18
src/lib/atproto/collection-icons.ts
··· 1 - export type CollectionIconMatch = { prefix: string; label: string; icon: string }; 1 + import type { CollectionIconMatch } from './types'; 2 + 3 + enum BasePath { 4 + atmologo = '/atmologos/color', 5 + namespace = '/icons/namespaces' 6 + } 2 7 3 - const atmologoBasePath = '/atmologos/color'; 8 + const namespaceIcon = (ns: string) => `${BasePath.namespace}/${ns.replaceAll('.', '/')}/icon.svg`; 4 9 5 10 export const collectionIconMatches: readonly CollectionIconMatch[] = [ 6 - { prefix: 'app.blento.', label: 'Blento', icon: `${atmologoBasePath}/blento.svg` }, 7 - { prefix: 'app.bsky.', label: 'Bluesky', icon: `${atmologoBasePath}/bluesky.svg` }, 8 - { prefix: 'at.margin.', label: 'Margin', icon: `${atmologoBasePath}/margin.svg` }, 9 - { prefix: 'blog.pckt.', label: 'Pckt', icon: `${atmologoBasePath}/pckt.svg` }, 10 - { prefix: 'dev.npmx.', label: 'npmx', icon: `${atmologoBasePath}/npmx.svg` }, 11 - { prefix: 'fm.plyr.', label: 'plyr.fm', icon: `${atmologoBasePath}/plyr.fm.svg` }, 12 - { prefix: 'id.sifa.', label: 'Sifa', icon: `${atmologoBasePath}/sifa%20id.svg` }, 13 - { prefix: 'net.anisota.', label: 'Anisota', icon: `${atmologoBasePath}/anisota.svg` }, 14 - { prefix: 'network.cosmik.', label: 'Cosmik', icon: `${atmologoBasePath}/semble.svg` }, 15 - { prefix: 'pub.leaflet.', label: 'Leaflet', icon: `${atmologoBasePath}/leaflet.svg` }, 16 - { prefix: 'sh.tangled.', label: 'Tangled', icon: `${atmologoBasePath}/tangled.svg` }, 17 - { prefix: 'site.standard.', label: 'Standard Site', icon: `${atmologoBasePath}/standard%20site.svg` }, 18 - { prefix: 'so.sprk.', label: 'Spark', icon: `${atmologoBasePath}/spark.svg` }, 19 - { prefix: 'social.grain.', label: 'Grain', icon: `${atmologoBasePath}/grain.svg` }, 20 - { prefix: 'social.popfeed.', label: 'Popfeed', icon: `${atmologoBasePath}/popfeed.svg` } 11 + { prefix: 'chat.bsky.', label: 'Bluesky', icon: `${BasePath.atmologo}/bluesky.svg` }, 12 + { prefix: 'app.blento.', label: 'Blento', icon: `${BasePath.atmologo}/blento.svg` }, 13 + { prefix: 'app.bsky.', label: 'Bluesky', icon: `${BasePath.atmologo}/bluesky.svg` }, 14 + { prefix: 'at.inlay.', label: 'Inlay', icon: namespaceIcon('at.inlay') }, 15 + { prefix: 'at.margin.', label: 'Margin', icon: `${BasePath.atmologo}/margin.svg` }, 16 + { prefix: 'blog.pckt.', label: 'Pckt', icon: `${BasePath.atmologo}/pckt.svg` }, 17 + { prefix: 'com.atproto.', label: 'ATProto', icon: namespaceIcon('com.atproto') }, 18 + { prefix: 'com.germnetwork.', label: 'Germ', icon: namespaceIcon('com.germnetwork') }, 19 + { prefix: 'community.lexicon.', label: 'Community', icon: namespaceIcon('com.atproto') }, 20 + { prefix: 'computer.aetheros.', label: 'Aether OS', icon: namespaceIcon('computer.aetheros') }, 21 + { prefix: 'dev.npmx.', label: 'npmx', icon: `${BasePath.atmologo}/npmx.svg` }, 22 + { prefix: 'fm.plyr.', label: 'plyr.fm', icon: `${BasePath.atmologo}/plyr.fm.svg` }, 23 + { prefix: 'id.sifa.', label: 'Sifa', icon: `${BasePath.atmologo}/sifa%20id.svg` }, 24 + { prefix: 'net.anisota.', label: 'Anisota', icon: `${BasePath.atmologo}/anisota.svg` }, 25 + { prefix: 'network.cosmik.', label: 'Cosmik', icon: `${BasePath.atmologo}/semble.svg` }, 26 + { prefix: 'pub.leaflet.', label: 'Leaflet', icon: `${BasePath.atmologo}/leaflet.svg` }, 27 + { prefix: 'sh.tangled.', label: 'Tangled', icon: `${BasePath.atmologo}/tangled.svg` }, 28 + { prefix: 'site.standard.', label: 'Standard Site', icon: `${BasePath.atmologo}/standard%20site.svg` }, 29 + { prefix: 'so.sprk.', label: 'Spark', icon: `${BasePath.atmologo}/spark.svg` }, 30 + { prefix: 'social.grain.', label: 'Grain', icon: `${BasePath.atmologo}/grain.svg` }, 31 + { prefix: 'social.popfeed.', label: 'Popfeed', icon: `${BasePath.atmologo}/popfeed.svg` } 21 32 ]; 22 33 23 34 export function collectionIconMatch(collection: string): CollectionIconMatch | null { 24 - return collectionIconMatches.find((match) => collection.startsWith(match.prefix)) ?? null; 35 + return ( 36 + collectionIconMatches 37 + .filter((match) => collection.startsWith(match.prefix)) 38 + .sort((a, b) => b.prefix.length - a.prefix.length)[0] ?? null 39 + ); 25 40 } 26 41 27 42 export function appLabelForCollection(collection: string): string | null {
+2
src/lib/atproto/types.ts
··· 46 46 47 47 export type CollectionRouteParams = Pick<RecordRouteParams, 'did' | 'collection'>; 48 48 49 + export type CollectionIconMatch = { prefix: string; label: string; icon: string }; 50 + 49 51 export type UnknownRecord = { uri: string; cid: string; value: unknown }; 50 52 51 53 export function isRecordValue(value: unknown): value is Record<string, unknown> {
+13
static/icons/namespaces/at/inlay/icon.svg
··· 1 + <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="1024" height="1024"> 2 + <defs> 3 + <linearGradient id="grad" gradientUnits="userSpaceOnUse" x1="60" y1="452" x2="452" y2="60"> 4 + <stop offset="0%" stop-color="#a370f7"/> 5 + <stop offset="45.1030%" stop-color="#a370f7"/> 6 + <stop offset="45.1030%" stop-color="#a370f7" stop-opacity="0"/> 7 + <stop offset="54.8970%" stop-color="#22a6e0" stop-opacity="0"/> 8 + <stop offset="54.8970%" stop-color="#22a6e0"/> 9 + <stop offset="100%" stop-color="#22a6e0"/> 10 + </linearGradient> 11 + </defs> 12 + <path d="M486.000000 256.000000 C486.000000 298.358497 486.085336 325.991354 484.337828 350.580625 C481.554446 389.745740 473.723644 425.088707 449.406176 449.406176 C425.088710 473.723641 389.745748 481.554445 350.580625 484.337828 C325.991354 486.085336 298.358504 486.000000 256.000000 486.000000 C213.641496 486.000000 186.008646 486.085336 161.419375 484.337828 C122.254252 481.554445 86.911290 473.723641 62.593824 449.406176 C38.276356 425.088707 30.445554 389.745740 27.662172 350.580625 C25.914664 325.991354 26.000000 298.358497 26.000000 256.000000 C26.000000 213.641503 25.914664 186.008646 27.662172 161.419375 C30.445554 122.254260 38.276356 86.911293 62.593824 62.593824 C86.911290 38.276359 122.254252 30.445555 161.419375 27.662172 C186.008646 25.914664 213.641496 26.000000 256.000000 26.000000 C298.358504 26.000000 325.991354 25.914664 350.580625 27.662172 C389.745748 30.445555 425.088710 38.276359 449.406176 62.593824 C473.723644 86.911293 481.554446 122.254260 484.337828 161.419375 C486.085336 186.008646 486.000000 213.641503 486.000000 256.000000Z M398.147817 256.000000 C398.147817 282.178991 398.200558 299.257036 397.120539 314.454041 C395.400314 338.659413 390.560612 360.502568 375.531590 375.531590 C360.502570 390.560610 338.659418 395.400313 314.454041 397.120539 C299.257036 398.200558 282.178995 398.147817 256.000000 398.147817 C229.821005 398.147817 212.742964 398.200558 197.545959 397.120539 C173.340582 395.400313 151.497430 390.560610 136.468410 375.531590 C121.439388 360.502568 116.599686 338.659413 114.879461 314.454041 C113.799442 299.257036 113.852183 282.178991 113.852183 256.000000 C113.852183 229.821009 113.799442 212.742964 114.879461 197.545959 C116.599686 173.340587 121.439388 151.497432 136.468410 136.468410 C151.497430 121.439390 173.340582 116.599687 197.545959 114.879461 C212.742964 113.799442 229.821005 113.852183 256.000000 113.852183 C282.178995 113.852183 299.257036 113.799442 314.454041 114.879461 C338.659418 116.599687 360.502570 121.439390 375.531590 136.468410 C390.560612 151.497432 395.400314 173.340587 397.120539 197.545959 C398.200558 212.742964 398.147817 229.821009 398.147817 256.000000Z" fill="url(#grad)" fill-rule="evenodd"/> 13 + </svg>
+4
static/icons/namespaces/com/atproto/icon.svg
··· 1 + <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16"> 2 + <path d="M0 0h16v16H0z" fill="none" /> 3 + <path fill="#01a6ff" fill-rule="evenodd" d="M9.774 1.747a6.5 6.5 0 1 0 1.142 12.062a.75.75 0 0 1 .673 1.34A8 8 0 1 1 16 8v1.25a2.75 2.75 0 0 1-5.072 1.475A4 4 0 1 1 12 8v1.25a1.25 1.25 0 0 0 2.5 0V8a6.5 6.5 0 0 0-4.726-6.253M10.5 8a2.5 2.5 0 1 0-5 0a2.5 2.5 0 0 0 5 0" clip-rule="evenodd" /> 4 + </svg>
+5
static/icons/namespaces/com/germnetwork/icon.svg
··· 1 + <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 512 512"> 2 + <path d="M0 0h512v512H0z" fill="none" /> 3 + <path fill="#3BCCFF" d="M167.935 31.49a240 240 0 0 1 28.715-9.205a241 241 0 0 1 33.659-5.98c2.23 9.985 1.836 12.318-1.218 29.602c-2.443-4.684-4.411-9.709-7.462-13.957c-5.144-7.163-12.117-5.83-15.671 2.568c-3.185 7.527-11.048 12.758-18.467 11.891c-1.669-.195-4.415-1.53-4.584-2.654c-1.535-10.205-8.126-11.471-14.972-12.265M314.66 46.278l-.433-.437l.471.444c-2.97-3.778-6.283-7.34-8.831-11.385c-3.387-5.376-6.371-11.006-9.451-16.576a242 242 0 0 0-15.996-2.151c2.391 17.649 12.329 26.365 34.24 30.105m-67.989 91.825c3.037-.459 5.775-2.62 8.785-3.613c3.766-1.243 10.388 3.164 10.892-3.463c.243-3.193-4.578-7.377-7.936-10.079c-3.918-3.152-8.664-5.344-13.266-7.494c-.643-.3-3.699 2.907-3.637 2.99c4.687 6.248 1.081 11.974-2.013 19.283c2.706.971 5.094 2.69 7.175 2.376M498.049 257c0 133.68-108.369 242.049-242.049 242.049S13.951 390.68 13.951 257c0-56.103 19.101-107.737 51.136-148.784c5.392 3.867 10.79 7.725 16.469 11.109c6.492 3.869 8.534 9.078 8.222 16.11c-.258 5.81-1.045 11.864.197 17.407c1.783 7.957 3.14 17.514 8.308 22.92c14.362 15.027 25.697 32.071 37.467 48.925c4.351 6.23 6.707 4.11 8.16-2.244c.453-1.981 2.634-3.566 4.023-5.333c1.305 1.209 3.138 2.171 3.835 3.664c9.982 21.378 26.649 33.883 49.666 38.594c3.19.653 7.693 3.277 8.451 5.897c2.595 8.967 8.733 10.285 16.43 9.787c7.065-.457 12.599 1.408 15.349 8.827c3.677 9.92 9.965 15.422 21.695 15.42c8.139-.001 9.23 3.55 6.608 11.678c-.984 3.052-2.158 6.046-3.057 9.121c-6.489 22.2-4.676 42.16 15.389 57.277c3.087 2.325 5.803 5.144 8.678 7.748c8.642 7.827 12.631 17.512 12.657 29.231c.031 13.655-1.055 27.019-6.232 39.825c-2.947 7.291-6.077 15.99.932 21.325c6.741 5.132 14.87.631 21.634-3.427c2.748-1.648 5.06-4.01 7.646-5.946c9.812-7.347 19.354-15.109 29.57-21.847c10.528-6.943 18.674-15.401 24.291-26.847c6.045-12.32 14.277-22.955 27.598-28.684c13.633-5.862 19.447-18.478 24.561-31.038c3.443-8.455 1.813-17.093-6.333-22.345c-6.886-4.439-14.389-8.46-22.179-10.809c-7.823-2.359-12.822-5.94-17.249-13.198c-12.445-20.404-30.285-33.004-55.43-32.486c-4.514.093-9.549 1.017-13.461-.59c-12.011-4.934-21.706-2.2-32.488 4.516c-13.16 8.197-21.322 2.923-22.406-12.796c-.374-5.425-.504-11.582-6.201-12.929c-11.93-2.82-17.913-7.178-10.137-19.831c.724-1.178-2.44-6.836-4.184-7.035c-4.732-.54-10.113-.275-14.399 1.593c-3.895 1.698-6.465 6.211-10.026 8.958c-4.192 3.234-14.298 1-17.065-3.358c-7.401-11.656-4.608-32.061 5.71-38.974c10.363-6.943 22.241-5.432 33.827-5.119c6.936.187 9.398 5.595 12.828 10.362c3.898 5.419 6.959 14.32 15.612 11.407c7.558-2.545 7.897-10.999 8.656-18.118a8.4 8.4 0 0 0-.026-1.938c-1.768-13.682 5.967-22.901 14.187-32.449c8.784-10.203 17.331-18.801 32.601-16.041c3.312.599 7.465-3.46 11.231-5.374c-1.88-2.992-3.096-6.973-5.777-8.77c-5.662-3.795-2.972-6.721.86-7.709c5.927-1.529 11.738-2.86 17.903 2.415c7.648 6.544 14.06 5.179 17.523-1.163c4.145-7.589 1.957-14.85-5.528-19.388c-21.44-12.999-42.813-26.108-64.212-39.174c-5.355-1.635-10.789-1.366-13.979 3.403c-2.295 3.431-2.957 8.08-3.818 12.294c-.503 2.46.293 5.156.054 7.704c-.476 5.092-5.726 8.399-9.379 5.109c-9.309-8.383-19.119-11.404-31.644-8.872c-4.049.818-10.086-2.543-10.146-9.391c-.06-6.768 2.508-11.638 9.832-11.513c8.79.15 14.248-2.125 16.152-12.025c.954-4.958 14.368-7.619 18.644-2.773c7.476 8.47 18.067 8.388 26.705 13.155c4.459.462 8.928 1.393 13.374 1.287c8.809-.21 9.727-2.307 6.215-12.466c-.409-1.184-.901-2.339-1.355-3.508l.032.032l.413.417l-.004-.005l.004.005l-.142-.145l-.308-.315c21.269 8.955 43.962 14.551 59.806 34.09c11.696 14.423 29.819 12.387 41.989-2.181c-3.308-3.734-6.209-7.984-9.82-11.333c43.952 36.326 74.863 87.872 84.645 146.57A243.5 243.5 0 0 1 498.049 257" /> 4 + <path fill="#13A031" d="M305.867 34.9c-3.387-5.376-6.371-11.006-9.451-16.576a241 241 0 0 1 33.625 8.165c23.741 7.62 45.882 18.809 65.798 32.93a340 340 0 0 1 8.323 6.177a242 242 0 0 1 5.935 4.749c3.612 3.349 6.513 7.599 9.82 11.333c-12.17 14.568-30.293 16.604-41.989 2.181c-15.844-19.539-38.537-25.135-59.806-34.09l.004.01l-3.467-3.501l.038.007l-.471-.444l.471.444c-2.97-3.779-6.282-7.341-8.83-11.385m20.543 198.757c-1.859-1.23-5.021-.864-7.548-.642c-8.781.771-16.016-1.26-22.597-7.933c-3.109-3.153-9.212-3.353-10.418-3.743c-5.838 0-7.786-.168-9.698.027c-11.421 1.167-19.55 6.392-19.48 12.422c.069 6.011 7.747 10.027 20.62 9.419c9.26-.438 16.738.409 24.431 7.399c8.276 7.52 21.486 5.951 28.337-.804c2.023-1.994 4.111-5.969 3.422-8.178c-.981-3.137-4.14-6.03-7.069-7.967m168.36-17.612c-8.158-8.158-23.52-10.361-28.77 13.297s7.558 65.711 29.986 57.408c2.699-23.705 2.131-47.311-1.216-70.705m-413.214-96.72c-5.679-3.384-11.077-7.242-16.469-11.109a243.5 243.5 0 0 1 25.867-28.268a243 243 0 0 1 27.207-21.941a241.4 241.4 0 0 1 49.774-26.517c6.845.794 13.437 2.06 14.973 12.265c.169 1.124 2.914 2.459 4.584 2.654c7.419.867 15.282-4.364 18.467-11.891c3.554-8.398 10.527-9.731 15.671-2.568c3.051 4.248 5.019 9.272 7.462 13.957c3.054-17.284 3.448-19.618 1.218-29.602c1.483-.156 2.969-.303 4.459-.433a245 245 0 0 1 45.652.301c2.39 17.649 12.328 26.365 34.239 30.105l3.468 3.501c.454 1.168.946 2.324 1.355 3.508c3.512 10.159 2.594 12.255-6.215 12.466c-4.445.106-8.915-.825-13.374-1.287c-8.638-4.767-19.23-4.685-26.705-13.155c-4.277-4.845-17.691-2.184-18.644 2.773c-1.904 9.899-7.362 12.175-16.152 12.025c-7.325-.125-9.893 4.745-9.832 11.513c.061 6.848 6.098 10.209 10.146 9.391c12.525-2.532 22.335.489 31.644 8.872c3.653 3.29 8.903-.017 9.379-5.109c.238-2.548-.557-5.245-.054-7.704c.861-4.214 1.523-8.863 3.818-12.294c3.19-4.769 8.624-5.038 13.979-3.403c21.399 13.066 42.773 26.175 64.212 39.174c7.485 4.538 9.673 11.799 5.528 19.388c-3.464 6.342-9.875 7.707-17.523 1.163c-6.165-5.275-11.976-3.944-17.903-2.415c-3.832.988-6.522 3.914-.86 7.709c2.681 1.797 3.897 5.779 5.777 8.77c-3.766 1.914-7.92 5.972-11.231 5.374c-15.27-2.76-23.817 5.838-32.601 16.041c-8.22 9.547-15.955 18.767-14.187 32.449c.082.637.094 1.299.026 1.938c-.759 7.118-1.098 15.573-8.656 18.118c-8.653 2.913-11.714-5.988-15.612-11.407c-3.43-4.767-5.891-10.175-12.828-10.362c-11.586-.312-23.464-1.824-33.827 5.119c-10.318 6.913-13.111 27.318-5.71 38.974c2.767 4.358 12.873 6.592 17.065 3.358c3.56-2.746 6.131-7.26 10.026-8.958c4.286-1.868 9.667-2.133 14.399-1.593c1.744.199 4.908 5.857 4.184 7.035c-7.775 12.653-1.792 17.011 10.137 19.831c5.697 1.347 5.827 7.504 6.201 12.929c1.084 15.719 9.245 20.993 22.406 12.796c10.782-6.716 20.477-9.45 32.488-4.516c3.912 1.607 8.946.683 13.461.59c25.145-.517 42.985 12.083 55.43 32.486c4.427 7.259 9.426 10.839 17.249 13.198c7.79 2.349 15.292 6.37 22.179 10.809c8.147 5.251 9.776 13.89 6.333 22.345c-5.114 12.559-10.929 25.176-24.561 31.038c-13.321 5.728-21.553 16.363-27.598 28.684c-5.616 11.446-13.763 19.903-24.291 26.847c-10.216 6.738-19.758 14.5-29.57 21.847c-2.586 1.936-4.897 4.298-7.646 5.946c-6.765 4.057-14.893 8.559-21.634 3.427c-7.008-5.335-3.879-14.034-.932-21.325c5.176-12.806 6.262-26.169 6.232-39.825c-.026-11.719-4.015-21.403-12.657-29.231c-2.875-2.604-5.591-5.423-8.678-7.748c-20.065-15.117-21.878-35.077-15.389-57.277c.899-3.075 2.073-6.069 3.057-9.121c2.622-8.128 1.531-11.679-6.608-11.678c-11.729.002-18.017-5.5-21.695-15.42c-2.75-7.419-8.284-9.284-15.349-8.827c-7.697.498-13.835-.82-16.43-9.787c-.758-2.62-5.261-5.244-8.451-5.897c-23.017-4.712-39.684-17.216-49.666-38.594c-.697-1.493-2.53-2.455-3.835-3.664c-1.39 1.766-3.57 3.352-4.023 5.333c-1.453 6.354-3.81 8.474-8.16 2.244c-11.77-16.854-23.105-33.897-37.467-48.925c-5.167-5.406-6.525-14.963-8.308-22.92c-1.242-5.544-.454-11.598-.197-17.407c.311-7.035-1.732-12.245-8.224-16.113" /> 5 + </svg>
+3
static/icons/namespaces/computer/aetheros/icon.svg
··· 1 + <svg xmlns="http://www.w3.org/2000/svg" width="210" height="186" fill="none" viewBox="0 0 210 186" class="size-8 text-primary"> 2 + <path fill="currentColor" d="M210 186H38l67-121 50 91H85l20-36 12.5 23H131l-26-47-41 74h116L105 34 21 186H0L105 0l105 186Z"></path> 3 + </svg>