Browse Source

reduce console logging noise

master
silberengel 3 months ago
parent
commit
5fd2783d6b
  1. 14
      src/lib/components/publications/CommentButton.svelte
  2. 50
      src/lib/components/publications/CommentLayer.svelte
  3. 209
      src/lib/components/publications/HighlightLayer.svelte
  4. 26
      src/lib/components/publications/HighlightSelectionHandler.svelte
  5. 129
      src/lib/components/publications/Publication.svelte
  6. 18
      src/lib/components/publications/PublicationSection.svelte
  7. 1
      src/lib/components/publications/TableOfContents.svelte
  8. 2
      src/routes/publication/[type]/[identifier]/+page.svelte

14
src/lib/components/publications/CommentButton.svelte

@ -129,12 +129,6 @@ @@ -129,12 +129,6 @@
commentEvent.tags.push(["e", eventId, relayHint]);
}
console.log("[CommentButton] Created NIP-22 comment event:", {
kind: commentEvent.kind,
tags: commentEvent.tags,
content: commentEvent.content,
});
return commentEvent;
}
@ -179,8 +173,6 @@ @@ -179,8 +173,6 @@
await commentEvent.sign($userStore.signer);
}
console.log("[CommentButton] Signed comment event:", commentEvent.rawEvent());
// Build relay list following the same pattern as eventServices
const relays = [
...communityRelays,
@ -191,8 +183,6 @@ @@ -191,8 +183,6 @@
// Remove duplicates
const uniqueRelays = Array.from(new Set(relays));
console.log("[CommentButton] Publishing to relays:", uniqueRelays);
const signedEvent = {
...plainEvent,
id: commentEvent.id,
@ -217,11 +207,9 @@ @@ -217,11 +207,9 @@
clearTimeout(timeout);
if (ok) {
publishedCount++;
console.log(`[CommentButton] Published to ${relayUrl}`);
WebSocketPool.instance.release(ws);
resolve();
} else {
console.warn(`[CommentButton] ${relayUrl} rejected: ${message}`);
WebSocketPool.instance.release(ws);
reject(new Error(message));
}
@ -240,8 +228,6 @@ @@ -240,8 +228,6 @@
throw new Error("Failed to publish to any relays");
}
console.log(`[CommentButton] Published to ${publishedCount} relay(s)`);
// Success!
success = true;
commentContent = "";

50
src/lib/components/publications/CommentLayer.svelte

@ -36,7 +36,6 @@ @@ -36,7 +36,6 @@
async function fetchComments() {
// Prevent concurrent fetches
if (loading) {
console.log("[CommentLayer] Already loading, skipping fetch");
return;
}
@ -55,8 +54,6 @@ @@ -55,8 +54,6 @@
// AI-NOTE: Mock mode allows testing comment UI without publishing to relays
// This is useful for development and demonstrating the comment system
if (useMockComments) {
console.log(`[CommentLayer] MOCK MODE - Generating mock comments for ${allAddresses.length} sections`);
try {
// Generate mock comment data
const mockComments = generateMockCommentsForSections(allAddresses);
@ -64,7 +61,6 @@ @@ -64,7 +61,6 @@
// Convert to NDKEvent instances (same as real events)
comments = mockComments.map(rawEvent => new NDKEventClass(ndk, rawEvent));
console.log(`[CommentLayer] Generated ${comments.length} mock comments`);
loading = false;
return;
} catch (err) {
@ -74,11 +70,6 @@ @@ -74,11 +70,6 @@
}
}
console.log(`[CommentLayer] Fetching comments for:`, {
eventIds: allEventIds,
addresses: allAddresses
});
try {
// Build filter for kind 1111 comment events
// IMPORTANT: Use only #a tags because filters are AND, not OR
@ -96,8 +87,6 @@ @@ -96,8 +87,6 @@
filter["#e"] = allEventIds;
}
console.log(`[CommentLayer] Fetching with filter:`, JSON.stringify(filter, null, 2));
// Build explicit relay set (same pattern as HighlightLayer)
const relays = [
...communityRelays,
@ -105,7 +94,6 @@ @@ -105,7 +94,6 @@
...$activeInboxRelays,
];
const uniqueRelays = Array.from(new Set(relays));
console.log(`[CommentLayer] Fetching from ${uniqueRelays.length} relays:`, uniqueRelays);
/**
* Use WebSocketPool with nostr-tools protocol instead of NDK
@ -131,14 +119,12 @@ @@ -131,14 +119,12 @@
const checkAllResponses = () => {
responseCount++;
if (responseCount >= totalRelays && loading) {
console.log(`[CommentLayer] All ${totalRelays} relays have responded, clearing loading state`);
loading = false;
}
};
const fetchPromises = uniqueRelays.map(async (relayUrl) => {
try {
console.log(`[CommentLayer] Connecting to ${relayUrl}`);
const ws = await WebSocketPool.instance.acquire(relayUrl);
return new Promise<void>((resolve) => {
@ -173,19 +159,8 @@ @@ -173,19 +159,8 @@
try {
const message = JSON.parse(event.data);
// Log ALL messages from relay.nostr.band for debugging
if (relayUrl.includes('relay.nostr.band')) {
console.log(`[CommentLayer] RAW message from ${relayUrl}:`, message);
}
if (message[0] === "EVENT" && message[1] === subscriptionId) {
const rawEvent = message[2];
console.log(`[CommentLayer] EVENT from ${relayUrl}:`, {
id: rawEvent.id,
kind: rawEvent.kind,
content: rawEvent.content.substring(0, 50),
tags: rawEvent.tags
});
// Avoid duplicates
if (!receivedEventIds.has(rawEvent.id)) {
@ -194,16 +169,11 @@ @@ -194,16 +169,11 @@
// Convert to NDKEvent
const ndkEvent = new NDKEventClass(ndk, rawEvent);
comments = [...comments, ndkEvent];
console.log(`[CommentLayer] Added comment, total now: ${comments.length}`);
}
} else if (message[0] === "EOSE" && message[1] === subscriptionId) {
console.log(`[CommentLayer] EOSE from ${relayUrl} (${responseCount + 1}/${totalRelays})`);
// Close subscription and release connection
releaseConnection();
safeResolve();
} else if (message[0] === "NOTICE") {
console.warn(`[CommentLayer] NOTICE from ${relayUrl}:`, message[1]);
}
} catch (err) {
console.error(`[CommentLayer] Error processing message from ${relayUrl}:`, err);
@ -214,11 +184,6 @@ @@ -214,11 +184,6 @@
// Send REQ
const req = ["REQ", subscriptionId, filter];
if (relayUrl.includes('relay.nostr.band')) {
console.log(`[CommentLayer] Sending REQ to ${relayUrl}:`, JSON.stringify(req));
} else {
console.log(`[CommentLayer] Sending REQ to ${relayUrl}`);
}
ws.send(JSON.stringify(req));
// Timeout per relay (5 seconds)
@ -240,16 +205,6 @@ @@ -240,16 +205,6 @@
// Ensure loading is cleared even if checkAllResponses didn't fire
loading = false;
console.log(`[CommentLayer] Fetched ${comments.length} comments`);
if (comments.length > 0) {
console.log(`[CommentLayer] Comments summary:`, comments.map(c => ({
content: c.content.substring(0, 30) + "...",
address: c.tags.find(t => t[0] === "a")?.[1],
author: c.pubkey.substring(0, 8)
})));
}
} catch (err) {
console.error(`[CommentLayer] Error fetching comments:`, err);
loading = false;
@ -265,8 +220,6 @@ @@ -265,8 +220,6 @@
const currentCount = eventIds.length + eventAddresses.length;
const hasEventData = currentCount > 0;
console.log(`[CommentLayer] Event data effect - count: ${currentCount}, lastFetched: ${lastFetchedCount}, loading: ${loading}`);
// Only fetch if:
// 1. We have event data
// 2. The count has changed since last fetch
@ -279,7 +232,6 @@ @@ -279,7 +232,6 @@
// Debounce: wait 500ms for more events to arrive before fetching
fetchTimeout = setTimeout(() => {
console.log(`[CommentLayer] Event data stabilized at ${currentCount} events, fetching comments...`);
lastFetchedCount = currentCount;
fetchComments();
}, 500);
@ -297,8 +249,6 @@ @@ -297,8 +249,6 @@
* Public method to refresh comments (e.g., after creating a new one)
*/
export function refresh() {
console.log("[CommentLayer] Manual refresh triggered");
// Clear existing comments
comments = [];

209
src/lib/components/publications/HighlightLayer.svelte

@ -75,7 +75,6 @@ @@ -75,7 +75,6 @@
async function fetchHighlights() {
// Prevent concurrent fetches
if (loading) {
console.log("[HighlightLayer] Already loading, skipping fetch");
return;
}
@ -99,10 +98,6 @@ @@ -99,10 +98,6 @@
// AI-NOTE: Mock mode allows testing highlight UI without publishing to relays
// This is useful for development and demonstrating the highlight system
if (useMockHighlights) {
console.log(
`[HighlightLayer] MOCK MODE - Generating mock highlights for ${allAddresses.length} sections`,
);
try {
// Generate mock highlight data
const mockHighlights = generateMockHighlightsForSections(allAddresses);
@ -112,9 +107,6 @@ @@ -112,9 +107,6 @@
(rawEvent) => new NDKEventClass(ndk, rawEvent),
);
console.log(
`[HighlightLayer] Generated ${highlights.length} mock highlights`,
);
loading = false;
return;
} catch (err) {
@ -127,11 +119,6 @@ @@ -127,11 +119,6 @@
}
}
console.log(`[HighlightLayer] Fetching highlights for:`, {
eventIds: allEventIds,
addresses: allAddresses,
});
try {
// Build filter for kind 9802 highlight events
// IMPORTANT: Use only #a tags because filters are AND, not OR
@ -149,11 +136,6 @@ @@ -149,11 +136,6 @@
filter["#e"] = allEventIds;
}
console.log(
`[HighlightLayer] Fetching with filter:`,
JSON.stringify(filter, null, 2),
);
// Build explicit relay set (same pattern as HighlightSelectionHandler and CommentButton)
const relays = [
...communityRelays,
@ -161,10 +143,6 @@ @@ -161,10 +143,6 @@
...$activeInboxRelays,
];
const uniqueRelays = Array.from(new Set(relays));
console.log(
`[HighlightLayer] Fetching from ${uniqueRelays.length} relays:`,
uniqueRelays,
);
/**
* Use WebSocketPool with nostr-tools protocol instead of NDK
@ -186,7 +164,6 @@ @@ -186,7 +164,6 @@
const fetchPromises = uniqueRelays.map(async (relayUrl) => {
try {
console.log(`[HighlightLayer] Connecting to ${relayUrl}`);
const ws = await WebSocketPool.instance.acquire(relayUrl);
return new Promise<void>((resolve) => {
@ -220,22 +197,8 @@ @@ -220,22 +197,8 @@
try {
const message = JSON.parse(event.data);
// Log ALL messages from relay.nostr.band for debugging
if (relayUrl.includes("relay.nostr.band")) {
console.log(
`[HighlightLayer] RAW message from ${relayUrl}:`,
message,
);
}
if (message[0] === "EVENT" && message[1] === subscriptionId) {
const rawEvent = message[2];
console.log(`[HighlightLayer] EVENT from ${relayUrl}:`, {
id: rawEvent.id,
kind: rawEvent.kind,
content: rawEvent.content.substring(0, 50),
tags: rawEvent.tags,
});
// Avoid duplicates
if (!receivedEventIds.has(rawEvent.id)) {
@ -244,27 +207,16 @@ @@ -244,27 +207,16 @@
// Convert to NDKEvent
const ndkEvent = new NDKEventClass(ndk, rawEvent);
highlights = [...highlights, ndkEvent];
console.log(
`[HighlightLayer] Added highlight, total now: ${highlights.length}`,
);
}
} else if (
message[0] === "EOSE" &&
message[1] === subscriptionId
) {
eoseCount++;
console.log(
`[HighlightLayer] EOSE from ${relayUrl} (${eoseCount}/${uniqueRelays.length})`,
);
// Close subscription and release connection
releaseConnection();
safeResolve();
} else if (message[0] === "NOTICE") {
console.warn(
`[HighlightLayer] NOTICE from ${relayUrl}:`,
message[1],
);
}
} catch (err) {
console.error(
@ -278,14 +230,6 @@ @@ -278,14 +230,6 @@
// Send REQ
const req = ["REQ", subscriptionId, filter];
if (relayUrl.includes("relay.nostr.band")) {
console.log(
`[HighlightLayer] Sending REQ to ${relayUrl}:`,
JSON.stringify(req),
);
} else {
console.log(`[HighlightLayer] Sending REQ to ${relayUrl}`);
}
ws.send(JSON.stringify(req));
// Timeout per relay (5 seconds)
@ -305,19 +249,6 @@ @@ -305,19 +249,6 @@
// Wait for all relays to respond or timeout
await Promise.all(fetchPromises);
console.log(`[HighlightLayer] Fetched ${highlights.length} highlights`);
if (highlights.length > 0) {
console.log(
`[HighlightLayer] Highlights summary:`,
highlights.map((h) => ({
content: h.content.substring(0, 30) + "...",
address: h.tags.find((t) => t[0] === "a")?.[1],
author: h.pubkey.substring(0, 8),
})),
);
}
loading = false;
// Rendering is handled by the visibility/highlights effect
@ -341,9 +272,6 @@ @@ -341,9 +272,6 @@
targetAddress?: string,
): boolean {
if (!containerRef) {
console.log(
`[HighlightLayer] Cannot highlight by position - no containerRef`,
);
return false;
}
@ -353,30 +281,10 @@ @@ -353,30 +281,10 @@
const sectionElement = document.getElementById(targetAddress);
if (sectionElement) {
searchRoot = sectionElement;
console.log(
`[HighlightLayer] Highlighting in specific section: ${targetAddress}`,
);
} else {
console.log(
`[HighlightLayer] Section ${targetAddress} not found in DOM, searching globally`,
);
}
}
console.log(
`[HighlightLayer] Applying position-based highlight ${offsetStart}-${offsetEnd}`,
);
const result = highlightByOffset(searchRoot, offsetStart, offsetEnd, color);
if (result) {
console.log(
`[HighlightLayer] Successfully applied position-based highlight`,
);
} else {
console.log(`[HighlightLayer] Failed to apply position-based highlight`);
}
return result;
return highlightByOffset(searchRoot, offsetStart, offsetEnd, color);
}
/**
@ -391,9 +299,6 @@ @@ -391,9 +299,6 @@
targetAddress?: string,
): void {
if (!containerRef || !text || text.trim().length === 0) {
console.log(
`[HighlightLayer] Cannot highlight - containerRef: ${!!containerRef}, text: "${text}"`,
);
return;
}
@ -403,21 +308,9 @@ @@ -403,21 +308,9 @@
const sectionElement = document.getElementById(targetAddress);
if (sectionElement) {
searchRoot = sectionElement;
console.log(
`[HighlightLayer] Searching in specific section: ${targetAddress}`,
);
} else {
console.log(
`[HighlightLayer] Section ${targetAddress} not found in DOM, searching globally`,
);
}
}
console.log(
`[HighlightLayer] Searching for text: "${text}" in`,
searchRoot,
);
// Use TreeWalker to find all text nodes
const walker = document.createTreeWalker(
searchRoot,
@ -432,22 +325,11 @@ @@ -432,22 +325,11 @@
}
// Search for the highlight text in text nodes
console.log(
`[HighlightLayer] Searching through ${textNodes.length} text nodes`,
);
for (const textNode of textNodes) {
const nodeText = textNode.textContent || "";
const index = nodeText.toLowerCase().indexOf(text.toLowerCase());
if (index !== -1) {
console.log(
`[HighlightLayer] Found match in text node:`,
nodeText.substring(
Math.max(0, index - 20),
Math.min(nodeText.length, index + text.length + 20),
),
);
const parent = textNode.parentNode;
if (!parent) continue;
@ -479,44 +361,26 @@ @@ -479,44 +361,26 @@
parent.replaceChild(fragment, textNode);
console.log(`[HighlightLayer] Highlighted text:`, match);
return; // Only highlight first occurrence to avoid multiple highlights
}
}
console.log(`[HighlightLayer] No match found for text: "${text}"`);
}
/**
* Render all highlights on the page
*/
function renderHighlights() {
console.log(
`[HighlightLayer] renderHighlights called - visible: ${visible}, containerRef: ${!!containerRef}, highlights: ${highlights.length}`,
);
if (!visible || !containerRef) {
console.log(
`[HighlightLayer] Skipping render - visible: ${visible}, containerRef: ${!!containerRef}`,
);
return;
}
if (highlights.length === 0) {
console.log(`[HighlightLayer] No highlights to render`);
return;
}
// Clear existing highlights
clearHighlights();
console.log(`[HighlightLayer] Rendering ${highlights.length} highlights`);
console.log(`[HighlightLayer] Container element:`, containerRef);
console.log(
`[HighlightLayer] Container has children:`,
containerRef.children.length,
);
// Apply each highlight
for (const highlight of highlights) {
const content = highlight.content;
@ -531,42 +395,19 @@ @@ -531,42 +395,19 @@
const hasOffset =
offsetTag && offsetTag[1] !== undefined && offsetTag[2] !== undefined;
console.log(`[HighlightLayer] Rendering highlight:`, {
hasOffset,
offsetTag,
content: content.substring(0, 50),
contentLength: content.length,
targetAddress,
color,
allTags: highlight.tags,
});
if (hasOffset) {
// Use position-based highlighting
const offsetStart = parseInt(offsetTag[1], 10);
const offsetEnd = parseInt(offsetTag[2], 10);
if (!isNaN(offsetStart) && !isNaN(offsetEnd)) {
console.log(
`[HighlightLayer] Using position-based highlighting: ${offsetStart}-${offsetEnd}`,
);
highlightByPosition(offsetStart, offsetEnd, color, targetAddress);
} else {
console.log(
`[HighlightLayer] Invalid offset values, falling back to text search`,
);
if (content && content.trim().length > 0) {
} else if (content && content.trim().length > 0) {
findAndHighlightText(content, color, targetAddress);
}
}
} else {
} else if (content && content.trim().length > 0) {
// Fall back to text-based highlighting
console.log(`[HighlightLayer] Using text-based highlighting`);
if (content && content.trim().length > 0) {
findAndHighlightText(content, color, targetAddress);
} else {
console.log(`[HighlightLayer] Skipping highlight - empty content`);
}
}
}
@ -595,10 +436,6 @@ @@ -595,10 +436,6 @@
parent.normalize();
}
});
console.log(
`[HighlightLayer] Cleared ${highlightElements.length} highlights`,
);
}
// Track the last fetched event count to know when to refetch
@ -610,10 +447,6 @@ @@ -610,10 +447,6 @@
const currentCount = eventIds.length + eventAddresses.length;
const hasEventData = currentCount > 0;
console.log(
`[HighlightLayer] Event data effect - count: ${currentCount}, lastFetched: ${lastFetchedCount}, loading: ${loading}`,
);
// Only fetch if:
// 1. We have event data
// 2. The count has changed since last fetch
@ -626,9 +459,6 @@ @@ -626,9 +459,6 @@
// Debounce: wait 500ms for more events to arrive before fetching
fetchTimeout = setTimeout(() => {
console.log(
`[HighlightLayer] Event data stabilized at ${currentCount} events, fetching highlights...`,
);
lastFetchedCount = currentCount;
fetchHighlights();
}, 500);
@ -646,14 +476,8 @@ @@ -646,14 +476,8 @@
$effect(() => {
// This effect runs when either visible or highlights.length changes
const highlightCount = highlights.length;
console.log(
`[HighlightLayer] Visibility/highlights effect - visible: ${visible}, highlights: ${highlightCount}`,
);
if (visible && highlightCount > 0) {
console.log(
`[HighlightLayer] Both visible and highlights ready, rendering...`,
);
renderHighlights();
} else if (!visible) {
clearHighlights();
@ -673,9 +497,6 @@ @@ -673,9 +497,6 @@
*/
async function fetchAuthorProfiles() {
const uniquePubkeys = Array.from(groupedHighlights.keys());
console.log(
`[HighlightLayer] Fetching profiles for ${uniquePubkeys.length} authors`,
);
for (const pubkey of uniquePubkeys) {
try {
@ -713,27 +534,17 @@ @@ -713,27 +534,17 @@
* Scroll to a specific highlight in the document
*/
function scrollToHighlight(highlight: NDKEvent) {
console.log(
`[HighlightLayer] scrollToHighlight called for:`,
highlight.content.substring(0, 50),
);
if (!containerRef) {
console.warn(`[HighlightLayer] No containerRef available`);
return;
}
const content = highlight.content;
if (!content || content.trim().length === 0) {
console.warn(`[HighlightLayer] No content in highlight`);
return;
}
// Find the highlight mark element
const highlightMarks = containerRef.querySelectorAll("mark.highlight");
console.log(
`[HighlightLayer] Found ${highlightMarks.length} highlight marks in DOM`,
);
// Try exact match first
for (const mark of highlightMarks) {
@ -741,9 +552,6 @@ @@ -741,9 +552,6 @@
const searchText = content.toLowerCase();
if (markText === searchText) {
console.log(
`[HighlightLayer] Found exact match, scrolling and flashing`,
);
// Scroll to this element
mark.scrollIntoView({ behavior: "smooth", block: "center" });
@ -762,9 +570,6 @@ @@ -762,9 +570,6 @@
const searchText = content.toLowerCase();
if (markText.includes(searchText) || searchText.includes(markText)) {
console.log(
`[HighlightLayer] Found partial match, scrolling and flashing`,
);
mark.scrollIntoView({ behavior: "smooth", block: "center" });
mark.classList.add("highlight-flash");
setTimeout(() => {
@ -773,11 +578,6 @@ @@ -773,11 +578,6 @@
return;
}
}
console.warn(
`[HighlightLayer] Could not find highlight mark for:`,
content.substring(0, 50),
);
}
/**
@ -790,7 +590,6 @@ @@ -790,7 +590,6 @@
try {
await navigator.clipboard.writeText(naddr);
copyFeedback = highlight.id;
console.log(`[HighlightLayer] Copied naddr to clipboard:`, naddr);
// Clear feedback after 2 seconds
setTimeout(() => {
@ -812,8 +611,6 @@ @@ -812,8 +611,6 @@
* Public method to refresh highlights (e.g., after creating a new one)
*/
export function refresh() {
console.log("[HighlightLayer] Manual refresh triggered");
// Clear existing highlights
highlights = [];
clearHighlights();

26
src/lib/components/publications/HighlightSelectionHandler.svelte

@ -97,7 +97,6 @@ @@ -97,7 +97,6 @@
// Don't use closest('.publication-leather') as Details also has that class
const publicationSection = target.closest("section[id]") as HTMLElement;
if (!publicationSection) {
console.log("[HighlightSelectionHandler] No section[id] found, aborting");
return;
}
@ -105,14 +104,6 @@ @@ -105,14 +104,6 @@
const sectionAddress = publicationSection.dataset.eventAddress;
const sectionEventId = publicationSection.dataset.eventId;
console.log("[HighlightSelectionHandler] Selection in section:", {
element: publicationSection,
address: sectionAddress,
eventId: sectionEventId,
allDataAttrs: publicationSection.dataset,
sectionId: publicationSection.id,
});
currentSelection = selection;
selectedText = text;
selectedSectionAddress = sectionAddress;
@ -155,12 +146,6 @@ @@ -155,12 +146,6 @@
selectedSectionAddress || publicationEvent.tagAddress();
const useEventId = selectedSectionEventId || publicationEvent.id;
console.log("[HighlightSelectionHandler] Creating highlight with:", {
address: useAddress,
eventId: useEventId,
fallbackUsed: !selectedSectionAddress,
});
const tags: string[][] = [];
// Always prefer addressable events for publications
@ -227,11 +212,6 @@ @@ -227,11 +212,6 @@
// Remove duplicates
const uniqueRelays = Array.from(new Set(relays));
console.log(
"[HighlightSelectionHandler] Publishing to relays:",
uniqueRelays,
);
const signedEvent = {
...plainEvent,
id: event.id,
@ -256,15 +236,9 @@ @@ -256,15 +236,9 @@
clearTimeout(timeout);
if (ok) {
publishedCount++;
console.log(
`[HighlightSelectionHandler] Published to ${relayUrl}`,
);
WebSocketPool.instance.release(ws);
resolve();
} else {
console.warn(
`[HighlightSelectionHandler] ${relayUrl} rejected: ${message}`,
);
WebSocketPool.instance.release(ws);
reject(new Error(message));
}

129
src/lib/components/publications/Publication.svelte

@ -86,13 +86,6 @@ @@ -86,13 +86,6 @@
import.meta.env.VITE_USE_MOCK_HIGHLIGHTS === "true",
);
// Log initial state for debugging
console.log("[Publication] Mock data initialized:", {
envVars: {
VITE_USE_MOCK_COMMENTS: import.meta.env.VITE_USE_MOCK_COMMENTS,
VITE_USE_MOCK_HIGHLIGHTS: import.meta.env.VITE_USE_MOCK_HIGHLIGHTS,
},
});
// Derive all event IDs and addresses for highlight fetching
let allEventIds = $derived.by(() => {
@ -183,7 +176,6 @@ @@ -183,7 +176,6 @@
const { done, value } = iterResult;
if (done) {
console.log("[Publication] Iterator done, no more events");
isDone = true;
break;
}
@ -198,17 +190,14 @@ @@ -198,17 +190,14 @@
// AI-NOTE: Add event immediately to leaves so user sees it right away
leaves = [...leaves, value];
newEvents.push(value);
console.log(`[Publication] Added event ${i + 1}/${count} immediately. Total: ${leaves.length}`);
} else {
newEvents.push(null);
}
} else {
consecutiveNulls++;
console.log(`[Publication] Got null event (${consecutiveNulls}/${MAX_CONSECUTIVE_NULLS} consecutive nulls)`);
// Break early if we're getting too many nulls - likely no more content
if (consecutiveNulls >= MAX_CONSECUTIVE_NULLS) {
console.log("[Publication] Too many consecutive null events, assuming no more content");
isDone = true;
break;
}
@ -222,58 +211,24 @@ @@ -222,58 +211,24 @@
consecutiveNulls++;
if (consecutiveNulls >= MAX_CONSECUTIVE_NULLS) {
console.log("[Publication] Too many errors/consecutive nulls, stopping load");
break;
}
}
}
// Log final summary (events already added incrementally above)
// Check if we got valid events
const validEvents = newEvents.filter(e => e !== null);
if (validEvents.length > 0) {
console.log(
`[Publication] Load complete. Added ${validEvents.length} events. Total: ${leaves.length}`,
);
// Log sentinel position after adding content
requestAnimationFrame(() => {
requestAnimationFrame(() => {
if (sentinelRef) {
const rect = sentinelRef.getBoundingClientRect();
const viewportHeight = window.innerHeight;
const distanceBelowViewport = rect.top - viewportHeight;
console.log("[Publication] Sentinel position after loadMore", {
leavesCount: leaves.length,
sentinelTop: rect.top,
viewportHeight,
distanceBelowViewport,
isConnected: sentinelRef.isConnected,
});
}
});
});
} else if (newEvents.length > 0) {
if (validEvents.length === 0 && newEvents.length > 0) {
// We got through the loop but no valid events - might be done
console.log("[Publication] Completed load but got no valid events", {
newEventsLength: newEvents.length,
consecutiveNulls,
});
if (consecutiveNulls >= MAX_CONSECUTIVE_NULLS) {
isDone = true;
}
} else {
console.warn("[Publication] loadMore completed but no events were loaded", {
count,
newEventsLength: newEvents.length,
validEventsLength: validEvents.length,
});
}
} catch (error) {
console.error("[Publication] Error loading more content:", error);
// Don't mark as done on error - might be transient network issue
} finally {
isLoading = false;
console.log(`[Publication] Load complete. isLoading: ${isLoading}, isDone: ${isDone}, leaves: ${leaves.length}`);
// AI-NOTE: The ResizeObserver effect will handle checking sentinel position
// after content actually renders, so we don't need aggressive post-load checks here
@ -353,31 +308,14 @@ @@ -353,31 +308,14 @@
* Loads sections before a given address in the TOC order.
*/
async function loadSectionsBefore(referenceAddress: string, count: number = AUTO_LOAD_BATCH_SIZE) {
console.log("[Publication] loadSectionsBefore called:", {
referenceAddress,
count,
hasPublicationTree: !!publicationTree,
hasToc: !!toc,
isLoading,
isLoadingUpward
});
if (!publicationTree || !toc) {
console.log("[Publication] loadSectionsBefore: Early return (missing dependencies)");
return;
}
const allAddresses = getAllSectionAddresses();
const referenceIndex = allAddresses.indexOf(referenceAddress);
console.log("[Publication] loadSectionsBefore: Reference index:", {
referenceIndex,
totalAddresses: allAddresses.length,
referenceAddress
});
if (referenceIndex === -1 || referenceIndex === 0) {
console.log("[Publication] loadSectionsBefore: Early return (not found or at beginning)");
return; // Not found or already at beginning
}
@ -390,14 +328,7 @@ @@ -390,14 +328,7 @@
!loadedAddresses.has(addr) && !existingAddresses.has(addr)
);
console.log("[Publication] loadSectionsBefore: Addresses to load:", {
total: addressesToLoad.length,
filtered: addressesToLoadFiltered.length,
addresses: addressesToLoadFiltered
});
if (addressesToLoadFiltered.length === 0) {
console.log("[Publication] loadSectionsBefore: Early return (no addresses to load)");
return;
}
@ -419,19 +350,8 @@ @@ -419,19 +350,8 @@
}
}
console.log("[Publication] loadSectionsBefore: Loaded events:", {
total: newEvents.length,
valid: newEvents.filter(e => e !== null).length
});
if (newEvents.length > 0) {
const beforeCount = leaves.length;
leaves = insertEventsInOrder(newEvents, allAddresses);
console.log("[Publication] loadSectionsBefore: Updated leaves:", {
before: beforeCount,
after: leaves.length,
added: leaves.length - beforeCount
});
}
isLoading = false;
@ -500,14 +420,12 @@ @@ -500,14 +420,12 @@
*/
async function jumpToSection(targetAddress: string, windowSize: number = JUMP_WINDOW_SIZE) {
if (!publicationTree || !toc) {
console.warn("[Publication] publicationTree or toc not available for jump-to-section");
return;
}
// Check if target is already loaded
const alreadyLoaded = leaves.some(leaf => leaf?.tagAddress() === targetAddress);
if (alreadyLoaded) {
console.log(`[Publication] Section ${targetAddress} already loaded, scrolling to it`);
// Scroll to the section
const element = document.getElementById(targetAddress);
if (element) {
@ -520,7 +438,6 @@ @@ -520,7 +438,6 @@
const targetIndex = allAddresses.indexOf(targetAddress);
if (targetIndex === -1) {
console.warn(`[Publication] Target address ${targetAddress} not found in TOC`);
return;
}
@ -545,7 +462,6 @@ @@ -545,7 +462,6 @@
// There's a gap - fill it
gapStartIndex = lastLoadedIndex + 1;
gapEndIndex = jumpStartIndex - 1;
console.log(`[Publication] Gap detected: sections ${gapStartIndex}-${gapEndIndex} need to be loaded`);
}
// Collect all addresses to load (gap + jump window)
@ -569,8 +485,6 @@ @@ -569,8 +485,6 @@
}
}
console.log(`[Publication] Jump-to-section: loading ${addressesToLoad.length} sections (gap: ${gapStartIndex >= 0 ? `${gapStartIndex}-${gapEndIndex}` : 'none'}, window: ${jumpStartIndex}-${jumpEndIndex})`);
// Load events
const windowEvents: Array<{ address: string; event: NDKEvent | null; index: number }> = [];
for (const address of addressesToLoad) {
@ -601,8 +515,6 @@ @@ -601,8 +515,6 @@
// Update observer after DOM updates
updateFirstSectionObserver();
}, 100);
console.log(`[Publication] Jump-to-section complete. Loaded ${windowEvents.length} sections around ${targetAddress}`);
}
/**
@ -617,12 +529,9 @@ @@ -617,12 +529,9 @@
*/
async function backgroundLoadAllEvents() {
if (!publicationTree || !toc) {
console.warn("[Publication] publicationTree or toc is not available for background loading");
return;
}
console.log("[Publication] Starting background load of all events in level-layers (throttled)");
// Throttling configuration
const BATCH_SIZE = 10; // Process 3 addresses at a time
const BATCH_DELAY_MS = 200; // 200ms delay between batches
@ -663,8 +572,8 @@ @@ -663,8 +572,8 @@
queue.push(childAddress);
// Resolve the child event to populate TOC (non-blocking)
publicationTree.getEvent(childAddress).catch((error: unknown) => {
console.debug(`[Publication] Error fetching child event ${childAddress}:`, error);
publicationTree.getEvent(childAddress).catch(() => {
// Silently handle errors in background loading
});
}
}
@ -682,15 +591,11 @@ @@ -682,15 +591,11 @@
}
}
console.log(`[Publication] Completed level, processed ${currentLevelAddresses.length} addresses, queued ${queue.length} for next level`);
// Delay between levels to give main loading priority
if (queue.length > 0) {
await new Promise(resolve => setTimeout(resolve, LEVEL_DELAY_MS));
}
}
console.log("[Publication] Background load complete, processed", processedAddresses.size, "addresses");
}
// #endregion
@ -709,8 +614,6 @@ @@ -709,8 +614,6 @@
return; // Already initialized with this tree, don't reset
}
console.log("[Publication] New publication tree detected, resetting state");
// Reset state when publicationTree changes
leaves = [];
isLoading = false;
@ -726,7 +629,6 @@ @@ -726,7 +629,6 @@
}
// Load initial content after reset
console.log("[Publication] Loading initial content");
hasInitialized = true;
loadMore(INITIAL_LOAD_COUNT);
@ -735,11 +637,9 @@ @@ -735,11 +637,9 @@
// Wait a bit for toc to be initialized
setTimeout(() => {
if (toc && publicationTree) {
backgroundLoadAllEvents().catch((error) => {
console.error("[Publication] Error in background loading:", error);
backgroundLoadAllEvents().catch(() => {
// Silently handle errors in background loading
});
} else {
console.warn("[Publication] toc or publicationTree not available for background loading");
}
}, 100);
});
@ -802,7 +702,6 @@ @@ -802,7 +702,6 @@
}
function handleCommentPosted() {
console.log("[Publication] Comment posted, refreshing comment layer");
// Refresh the comment layer after a short delay to allow relay indexing
setTimeout(() => {
if (commentLayerRef) {
@ -855,8 +754,6 @@ @@ -855,8 +754,6 @@
await commentEvent.sign();
await commentEvent.publish();
console.log("[Publication] Article comment published:", commentEvent.id);
articleCommentSuccess = true;
articleCommentContent = "";
@ -891,11 +788,7 @@ @@ -891,11 +788,7 @@
eventAddress: indexEvent.tagAddress(),
eventKind: indexEvent.kind,
reason: "User deleted publication",
onSuccess: (deletionEventId) => {
console.log(
"[Publication] Deletion event published:",
deletionEventId,
);
onSuccess: () => {
publicationDeleted = true;
// Redirect after 2 seconds
@ -936,7 +829,6 @@ @@ -936,7 +829,6 @@
// AI-NOTE: TOC updates happen in parallel as sections mount, improving performance
const entry = toc.getEntry(address);
if (!entry) {
console.warn(`[Publication] No parent found for ${address}`);
return;
}
toc.buildTocFromDocument(el, entry);
@ -1004,29 +896,24 @@ @@ -1004,29 +896,24 @@
*/
async function handleUpwardLoad(referenceAddress: string, source: "top-sentinel" | "first-section") {
if (isLoadingUpward) {
console.log(`[Publication] Upward load from ${source} ignored (already loading)`);
return;
}
const now = Date.now();
if ((now - lastUpwardLoadTime) < UPWARD_LOAD_DEBOUNCE_MS) {
console.log(`[Publication] Upward load from ${source} debounced, time since last:`, now - lastUpwardLoadTime);
return;
}
const firstSection = leaves.filter(l => l !== null)[0];
if (!firstSection || firstSection.tagAddress() === rootAddress) {
console.log(`[Publication] Upward load from ${source} skipped (no valid first section or at root)`);
return;
}
const firstAddress = firstSection.tagAddress();
if (referenceAddress !== firstAddress && source === "first-section") {
console.log(`[Publication] Upward load from first-section skipped (address mismatch)`);
return;
}
console.log(`[Publication] Upward load from ${source}, loading sections before:`, firstAddress);
isLoadingUpward = true;
lastUpwardLoadTime = now;
@ -1043,7 +930,6 @@ @@ -1043,7 +930,6 @@
try {
await loadSectionsBefore(firstAddress, AUTO_LOAD_BATCH_SIZE);
console.log(`[Publication] Upward load from ${source} complete`);
// Wait for DOM stabilization before updating observer
setTimeout(() => {
@ -1240,7 +1126,6 @@ @@ -1240,7 +1126,6 @@
// Refresh highlights after a short delay to allow relay indexing
setTimeout(() => {
if (highlightLayerRef) {
console.log("[Publication] Refreshing highlights after creation");
highlightLayerRef.refresh();
}
}, 500);

18
src/lib/components/publications/PublicationSection.svelte

@ -63,10 +63,6 @@ @@ -63,10 +63,6 @@
leafEvent.then((e) => {
if (e?.id) {
leafEventId = e.id;
console.log(
`[PublicationSection] Set leafEventId for ${address}:`,
e.id,
);
}
});
});
@ -205,11 +201,7 @@ @@ -205,11 +201,7 @@
eventAddress: address,
eventKind: event.kind,
reason: "User deleted section",
onSuccess: (deletionEventId) => {
console.log(
"[PublicationSection] Deletion event published:",
deletionEventId,
);
onSuccess: () => {
// Refresh the page to reflect the deletion
window.location.reload();
},
@ -231,14 +223,6 @@ @@ -231,14 +223,6 @@
}
ref(sectionRef);
// Log data attributes for debugging
console.log(`[PublicationSection] Section mounted:`, {
address,
leafEventId,
dataAddress: sectionRef.dataset.eventAddress,
dataEventId: sectionRef.dataset.eventId,
});
});
</script>

1
src/lib/components/publications/TableOfContents.svelte

@ -92,7 +92,6 @@ @@ -92,7 +92,6 @@
const currentEntries = entries;
const lastEntry = currentEntries[currentEntries.length - 1];
if (lastEntry && lastEntry.address === address) {
console.debug('[TableOfContents] Last entry clicked, triggering load more');
onLoadMore?.();
}
}

2
src/routes/publication/[type]/[identifier]/+page.svelte

@ -90,8 +90,6 @@ @@ -90,8 +90,6 @@
function initializePublicationComponents(event: NDKEvent) {
if (!data.ndk) return;
console.log("[Publication] Initializing publication components for event:", event.tagAddress());
publicationTree = new SveltePublicationTree(event, data.ndk);
toc = new TableOfContents(
event.tagAddress(),

Loading…
Cancel
Save