diff --git a/src/lib/navigator/EventNetwork/Legend.svelte b/src/lib/navigator/EventNetwork/Legend.svelte
index 909cad8..63b9aaa 100644
--- a/src/lib/navigator/EventNetwork/Legend.svelte
+++ b/src/lib/navigator/EventNetwork/Legend.svelte
@@ -386,7 +386,7 @@
diff --git a/src/lib/navigator/EventNetwork/index.svelte b/src/lib/navigator/EventNetwork/index.svelte
index 8c91334..5d06c69 100644
--- a/src/lib/navigator/EventNetwork/index.svelte
+++ b/src/lib/navigator/EventNetwork/index.svelte
@@ -336,8 +336,8 @@
if (showPersonNodes) {
debug("Creating person anchor nodes");
- // Extract unique persons from events
- personMap = extractUniquePersons(events);
+ // Extract unique persons from events and follow lists
+ personMap = extractUniquePersons(events, followListEvents);
// Create person anchor nodes based on filters
const personResult = createPersonAnchorNodes(
@@ -639,8 +639,13 @@
return baseClasses;
})
.style("fill", (d: NetworkNode) => {
- // Person anchors are green
+ // Person anchors - color based on source
if (d.isPersonAnchor) {
+ // If from follow list, use kind 3 color
+ if (d.isFromFollowList) {
+ return getEventKindColor(3);
+ }
+ // Otherwise green for event authors
return "#10B981";
}
// Tag anchors get their specific colors
@@ -870,8 +875,17 @@
if (svgGroup) {
svgGroup
.selectAll("g.node")
- .select("circle.visual-circle")
+ .select(".visual-shape")
.style("fill", (d: NetworkNode) => {
+ // Person anchors - color based on source
+ if (d.isPersonAnchor) {
+ // If from follow list, use kind 3 color
+ if (d.isFromFollowList) {
+ return getEventKindColor(3);
+ }
+ // Otherwise green for event authors
+ return "#10B981";
+ }
if (d.isTagAnchor) {
return getTagAnchorColor(d.tagType || "");
}
diff --git a/src/lib/navigator/EventNetwork/types.ts b/src/lib/navigator/EventNetwork/types.ts
index d0d579c..67fe49f 100644
--- a/src/lib/navigator/EventNetwork/types.ts
+++ b/src/lib/navigator/EventNetwork/types.ts
@@ -58,6 +58,7 @@ export interface NetworkNode extends SimulationNodeDatum {
isPersonAnchor?: boolean; // Whether this is a person anchor node
pubkey?: string; // The person's public key
displayName?: string; // The person's display name from kind 0
+ isFromFollowList?: boolean; // Whether this person comes from follow lists
}
/**
diff --git a/src/lib/navigator/EventNetwork/utils/personNetworkBuilder.ts b/src/lib/navigator/EventNetwork/utils/personNetworkBuilder.ts
index 38f7ed7..5d9bfb9 100644
--- a/src/lib/navigator/EventNetwork/utils/personNetworkBuilder.ts
+++ b/src/lib/navigator/EventNetwork/utils/personNetworkBuilder.ts
@@ -44,6 +44,7 @@ function createSeed(str: string): number {
export interface PersonConnection {
signedByEventIds: Set;
referencedInEventIds: Set;
+ isFromFollowList?: boolean; // Track if this person comes from follow lists
}
/**
@@ -51,12 +52,33 @@ export interface PersonConnection {
* Tracks both signed-by (event.pubkey) and referenced (["p", pubkey] tags)
*/
export function extractUniquePersons(
- events: NDKEvent[]
+ events: NDKEvent[],
+ followListEvents?: NDKEvent[]
): Map {
// Map of pubkey -> PersonConnection
const personMap = new Map();
console.log(`[PersonBuilder] Extracting persons from ${events.length} events`);
+
+ // First collect pubkeys from follow list events
+ const followListPubkeys = new Set();
+ if (followListEvents && followListEvents.length > 0) {
+ console.log(`[PersonBuilder] Processing ${followListEvents.length} follow list events`);
+ followListEvents.forEach((event) => {
+ // Follow list author
+ if (event.pubkey) {
+ followListPubkeys.add(event.pubkey);
+ }
+ // People in follow lists (p tags)
+ if (event.tags) {
+ event.tags.forEach(tag => {
+ if (tag[0] === "p" && tag[1]) {
+ followListPubkeys.add(tag[1]);
+ }
+ });
+ }
+ });
+ }
events.forEach((event) => {
if (!event.id) return;
@@ -66,7 +88,8 @@ export function extractUniquePersons(
if (!personMap.has(event.pubkey)) {
personMap.set(event.pubkey, {
signedByEventIds: new Set(),
- referencedInEventIds: new Set()
+ referencedInEventIds: new Set(),
+ isFromFollowList: followListPubkeys.has(event.pubkey)
});
}
personMap.get(event.pubkey)!.signedByEventIds.add(event.id);
@@ -80,7 +103,8 @@ export function extractUniquePersons(
if (!personMap.has(referencedPubkey)) {
personMap.set(referencedPubkey, {
signedByEventIds: new Set(),
- referencedInEventIds: new Set()
+ referencedInEventIds: new Set(),
+ isFromFollowList: followListPubkeys.has(referencedPubkey)
});
}
personMap.get(referencedPubkey)!.referencedInEventIds.add(event.id);
@@ -90,6 +114,7 @@ export function extractUniquePersons(
});
console.log(`[PersonBuilder] Found ${personMap.size} unique persons`);
+ console.log(`[PersonBuilder] ${followListPubkeys.size} are from follow lists`);
return personMap;
}
@@ -172,6 +197,7 @@ export function createPersonAnchorNodes(
pubkey,
displayName,
connectedNodes: Array.from(connectedEventIds),
+ isFromFollowList: connection.isFromFollowList,
x,
y,
fx: x, // Fix position
@@ -241,6 +267,7 @@ export interface PersonAnchorInfo {
displayName: string;
signedByCount: number;
referencedCount: number;
+ isFromFollowList: boolean;
}
/**
@@ -257,6 +284,7 @@ export function extractPersonAnchorInfo(
displayName: anchor.displayName || "",
signedByCount: connection?.signedByEventIds.size || 0,
referencedCount: connection?.referencedInEventIds.size || 0,
+ isFromFollowList: connection?.isFromFollowList || false,
};
});
}
\ No newline at end of file
diff --git a/src/routes/visualize/+page.svelte b/src/routes/visualize/+page.svelte
index ee941f7..62885d0 100644
--- a/src/routes/visualize/+page.svelte
+++ b/src/routes/visualize/+page.svelte
@@ -509,8 +509,13 @@
// Use the utility function to extract ALL pubkeys (authors + p tags + content)
const allPubkeys = extractPubkeysFromEvents(allEvents);
- // Add pubkeys from follow lists if present
- if (followListEvents.length > 0) {
+ // Check if follow list is configured with limit > 0
+ const followListConfig = allConfigs.find(c => c.kind === 3);
+ const shouldIncludeFollowPubkeys = followListConfig && followListConfig.limit > 0;
+
+ // Add pubkeys from follow lists only if follow list limit > 0
+ if (shouldIncludeFollowPubkeys && followListEvents.length > 0) {
+ debug("Including pubkeys from follow lists (limit > 0)");
followListEvents.forEach(event => {
if (event.pubkey) allPubkeys.add(event.pubkey);
event.tags.forEach(tag => {
@@ -519,6 +524,8 @@
}
});
});
+ } else if (!shouldIncludeFollowPubkeys && followListEvents.length > 0) {
+ debug("Excluding follow list pubkeys (limit = 0, only fetching event authors)");
}
debug("Profile extraction complete:", {