From 9608b75636510a6913dddefb19ad5e64e0c79720 Mon Sep 17 00:00:00 2001
From: Claude
Date: Tue, 26 May 2026 05:51:51 +0000
Subject: [PATCH] TrendingLexicons: chat.bsky out of trending, chat.* out of
top, schema link, microcosm credit
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Three small refinements:
1. Hidden-prefix lists per mode:
- Trending hides app.bsky.* AND chat.bsky.* (both Bluesky flavors).
- Top hides chat.* (private DM traffic isn't a fair "what's hot"
signal). Bluesky public namespace stays in Top — it's the
elephant in the room and that's accurate to show.
2. Clicking a row now opens the lexicon's schema record on its
publisher, not the explorer's collection view. Convention: NSID
`..<...>` maps to publisher `.`, so
`net.anisota.foo` -> `anisota.net`. Deep link goes to the
explorer's record page at
`/explore//com.atproto.lexicon.schema/` and
reuses RecordPreview to render the schema doc. Falls through to
the explorer's not-found UI when the publisher hasn't published
one — acceptable fallback.
3. Small microcosm credit row at the bottom of the card:
"Data from microcosm.blue". UFOs is theirs; surface the
attribution.
---
src/components/explore/TrendingLexicons.tsx | 91 ++++++++++++++++++---
1 file changed, 80 insertions(+), 11 deletions(-)
diff --git a/src/components/explore/TrendingLexicons.tsx b/src/components/explore/TrendingLexicons.tsx
index 8351262..3edbe39 100644
--- a/src/components/explore/TrendingLexicons.tsx
+++ b/src/components/explore/TrendingLexicons.tsx
@@ -118,9 +118,7 @@ export default function TrendingLexicons() {
className="explore-placeholder"
style={{ padding: '1rem', margin: 0 }}
>
- {mode === 'trending'
- ? 'No non-Bluesky lexicons matched in this window.'
- : 'No lexicons matched in this window.'}
+ No lexicons matched in this window.
+ );
+}
+
function Header({
mode,
setMode,
@@ -310,8 +342,8 @@ function Row({
}}
>
nsid.startsWith(p));
}
/** First two segments — `app.bsky.feed.post` -> `app.bsky`. Single-segment
@@ -487,12 +534,13 @@ function namespaceKey(nsid: string): string {
function filterAndDedup(
rows: T[],
- dropBluesky: boolean,
+ mode: Mode,
): T[] {
+ const hidden = mode === 'trending' ? TRENDING_HIDDEN_PREFIXES : TOP_HIDDEN_PREFIXES;
const seen = new Set();
const out: T[] = [];
for (const r of rows) {
- if (dropBluesky && isBluesky(r.nsid)) continue;
+ if (hasHiddenPrefix(r.nsid, hidden)) continue;
const key = namespaceKey(r.nsid);
if (seen.has(key)) continue;
seen.add(key);
@@ -501,6 +549,27 @@ function filterAndDedup(
return out;
}
+/**
+ * Convention: an NSID like `..<...>` maps to `.`
+ * as the publisher's handle. `net.anisota.harvest.minigame` ->
+ * `anisota.net`, `app.bsky.feed.post` -> `bsky.app`, etc. Used to build
+ * the deep link into the explorer's lexicon-schema record for an NSID.
+ */
+function publisherForNsid(nsid: string): string {
+ const parts = nsid.split('.');
+ if (parts.length < 2) return nsid;
+ return `${parts[1]}.${parts[0]}`;
+}
+
+/** Lexicon-schema records live at this collection on the publisher's repo,
+ * keyed by the full NSID. The explorer's record page renders them nicely
+ * via RecordPreview, and falls through to a not-found message when the
+ * publisher hasn't published a schema. */
+function schemaPathFor(nsid: string): string {
+ const publisher = publisherForNsid(nsid);
+ return `/explore/${publisher}/com.atproto.lexicon.schema/${encodeURIComponent(nsid)}`;
+}
+
// ─── Fetching ──────────────────────────────────────────────────────────────
type RawCollection = {
@@ -552,8 +621,8 @@ async function fetchRanking(
orderForMetric(metric),
);
- // 2) Filter (bsky dropped only in trending) + dedup by top-2-segment ns.
- const filtered = filterAndDedup(candidates, mode === 'trending');
+ // 2) Filter (mode-specific) + dedup by top-2-segment namespace.
+ const filtered = filterAndDedup(candidates, mode);
if (filtered.length === 0) return [];
// 3) Score by the chosen metric. /collections gives us creates +
--
2.51.2