diff --git a/src/lib/components/publications/table_of_contents.svelte.ts b/src/lib/components/publications/table_of_contents.svelte.ts index 95fa0e2..afe8920 100644 --- a/src/lib/components/publications/table_of_contents.svelte.ts +++ b/src/lib/components/publications/table_of_contents.svelte.ts @@ -181,7 +181,7 @@ export class TableOfContents { return; } - const childAddresses = await this.#publicationTree.getChildAddresses(address); + const childAddresses = await this.#publicationTree.getChildAddresses(entry.address); for (const childAddress of childAddresses) { if (!childAddress) { continue; @@ -205,6 +205,8 @@ export class TableOfContents { this.addressMap.set(childAddress, childEntry); } + await this.#matchChildrenToTagOrder(entry); + entry.childrenResolved = true; } @@ -237,6 +239,31 @@ export class TableOfContents { return entry; } + /** + * Reorders the children of a ToC entry to match the order of 'a' tags in the corresponding + * Nostr index event. + * + * @param entry The ToC entry to reorder. + */ + async #matchChildrenToTagOrder(entry: TocEntry) { + const parentEvent = await this.#publicationTree.getEvent(entry.address); + if (parentEvent?.kind === indexKind) { + const tagOrder = parentEvent.getMatchingTags('a').map(tag => tag[1]); + const addressToOrdinal = new Map(); + + // Build map of addresses to their ordinals from tag order + tagOrder.forEach((address, index) => { + addressToOrdinal.set(address, index); + }); + + entry.children.sort((a, b) => { + const aOrdinal = addressToOrdinal.get(a.address) ?? Number.MAX_SAFE_INTEGER; + const bOrdinal = addressToOrdinal.get(b.address) ?? Number.MAX_SAFE_INTEGER; + return aOrdinal - bOrdinal; + }); + } + } + #buildTocEntryFromResolvedNode(address: string) { if (this.addressMap.has(address)) { return;