Browse Source

fix refactor

master
silberengel 3 months ago
parent
commit
2cb8266297
  1. 148
      src/lib/components/publications/Publication.svelte

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

@ -292,6 +292,61 @@
return addresses; return addresses;
} }
/**
* Inserts events into leaves array in TOC order, ensuring no duplicates.
* Returns the updated leaves array.
*/
function insertEventsInOrder(
eventsToInsert: Array<NDKEvent | null>,
allAddresses: string[]
): Array<NDKEvent | null> {
const existingAddresses = new Set(leaves.map(leaf => leaf?.tagAddress()).filter(Boolean));
const newLeaves = [...leaves];
// Filter out nulls and duplicates
const validEvents = eventsToInsert.filter(event => {
if (!event) {
return false;
}
const address = event.tagAddress();
return address && !existingAddresses.has(address);
});
// Sort events by their TOC index
const sortedEvents = validEvents.sort((a, b) => {
const indexA = allAddresses.indexOf(a!.tagAddress());
const indexB = allAddresses.indexOf(b!.tagAddress());
return indexA - indexB;
});
// Insert each event at the correct position
for (const event of sortedEvents) {
const address = event!.tagAddress();
const index = allAddresses.indexOf(address);
// Find insertion point
let insertIndex = newLeaves.length;
for (let i = 0; i < newLeaves.length; i++) {
const leafAddress = newLeaves[i]?.tagAddress();
if (leafAddress) {
const leafIndex = allAddresses.indexOf(leafAddress);
if (leafIndex > index) {
insertIndex = i;
break;
}
}
}
// Only insert if not already present
if (!newLeaves.some(leaf => leaf?.tagAddress() === address)) {
newLeaves.splice(insertIndex, 0, event);
existingAddresses.add(address);
}
}
return newLeaves;
}
/** /**
* Loads sections before a given address in the TOC order. * Loads sections before a given address in the TOC order.
*/ */
@ -338,9 +393,8 @@
} }
} }
const validEvents = newEvents.filter(e => e !== null); if (newEvents.length > 0) {
if (validEvents.length > 0) { leaves = insertEventsInOrder(newEvents, allAddresses);
leaves = [...newEvents.reverse(), ...leaves];
} }
isLoading = false; isLoading = false;
@ -393,17 +447,7 @@
} }
if (newEvents.length > 0) { if (newEvents.length > 0) {
const referenceIndexInLeaves = leaves.findIndex( leaves = insertEventsInOrder(newEvents, allAddresses);
leaf => leaf?.tagAddress() === referenceAddress
);
if (referenceIndexInLeaves !== -1) {
const before = leaves.slice(0, referenceIndexInLeaves + 1);
const after = leaves.slice(referenceIndexInLeaves + 1);
leaves = [...before, ...newEvents, ...after];
} else {
leaves = [...leaves, ...newEvents];
}
} }
isLoading = false; isLoading = false;
@ -466,29 +510,9 @@
} }
} }
// Insert events in TOC order // Insert events in TOC order, ensuring no duplicates
const newLeaves = [...leaves]; const eventsToInsert: Array<NDKEvent | null> = windowEvents.map(({ event }) => event);
for (const { address, event, index } of windowEvents) { leaves = insertEventsInOrder(eventsToInsert, allAddresses);
// Skip if already in leaves
if (newLeaves.some(leaf => leaf?.tagAddress() === address)) {
continue;
}
let insertIndex = newLeaves.length;
for (let i = 0; i < newLeaves.length; i++) {
const leafAddress = newLeaves[i]?.tagAddress();
if (leafAddress) {
const leafIndex = allAddresses.indexOf(leafAddress);
if (leafIndex > index) {
insertIndex = i;
break;
}
}
}
newLeaves.splice(insertIndex, 0, event);
}
leaves = newLeaves;
// Set bookmark to target address for future sequential loading // Set bookmark to target address for future sequential loading
publicationTree.setBookmark(targetAddress); publicationTree.setBookmark(targetAddress);
@ -883,6 +907,7 @@
}); });
// AI-NOTE: Simple IntersectionObserver-based infinite scroll // AI-NOTE: Simple IntersectionObserver-based infinite scroll
// Observes sentinels and first section element for upward scrolling
$effect(() => { $effect(() => {
if (!hasInitialized || !publicationTree || !toc) { if (!hasInitialized || !publicationTree || !toc) {
return; return;
@ -890,6 +915,8 @@
let observer: IntersectionObserver | null = null; let observer: IntersectionObserver | null = null;
let setupTimeout: number | null = null; let setupTimeout: number | null = null;
let updateInterval: number | null = null;
let observedFirstSection: string | null = null;
const setupObserver = () => { const setupObserver = () => {
if (observer) { if (observer) {
@ -928,6 +955,12 @@
if (firstSection && firstSection.tagAddress() !== rootAddress) { if (firstSection && firstSection.tagAddress() !== rootAddress) {
loadSectionsBefore(firstSection.tagAddress(), AUTO_LOAD_BATCH_SIZE); loadSectionsBefore(firstSection.tagAddress(), AUTO_LOAD_BATCH_SIZE);
} }
} else {
// This is the first section element
const firstSection = leaves.filter(l => l !== null)[0];
if (firstSection && targetId === firstSection.tagAddress() && targetId !== rootAddress) {
loadSectionsBefore(targetId, AUTO_LOAD_BATCH_SIZE);
}
} }
break; break;
} }
@ -946,12 +979,51 @@
} }
}; };
setupTimeout = window.setTimeout(setupObserver, 100); // Update observer when first section changes (e.g., after jump)
const updateFirstSectionObserver = () => {
if (!observer || leaves.length === 0) {
return;
}
const firstSection = leaves.filter(l => l !== null)[0];
if (!firstSection) {
return;
}
const firstAddress = firstSection.tagAddress();
if (firstAddress === observedFirstSection || firstAddress === rootAddress) {
return;
}
// Unobserve previous first section if it changed
if (observedFirstSection) {
const prevElement = document.getElementById(observedFirstSection);
if (prevElement) {
observer.unobserve(prevElement);
}
}
// Observe new first section
const firstElement = document.getElementById(firstAddress);
if (firstElement) {
observer.observe(firstElement);
observedFirstSection = firstAddress;
}
};
setupTimeout = window.setTimeout(() => {
setupObserver();
// Start updating when first section changes
updateInterval = window.setInterval(updateFirstSectionObserver, 500);
}, 100);
return () => { return () => {
if (setupTimeout !== null) { if (setupTimeout !== null) {
clearTimeout(setupTimeout); clearTimeout(setupTimeout);
} }
if (updateInterval !== null) {
clearInterval(updateInterval);
}
if (observer) { if (observer) {
observer.disconnect(); observer.disconnect();
} }

Loading…
Cancel
Save