Browse Source

Correctly render hierarchy in ToC component

master
buttercat1791 9 months ago
parent
commit
15daf824c2
  1. 21
      src/lib/components/publications/TableOfContents.svelte
  2. 18
      src/lib/components/publications/table_of_contents.svelte.ts

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

@ -41,14 +41,10 @@
toc.expandedMap.set(address, expanded); toc.expandedMap.set(address, expanded);
entry.resolveChildren(); entry.resolveChildren();
} }
function handleEntryClick(address: string, expanded: boolean = false) {
setEntryExpanded(address, expanded);
onSectionFocused?.(address);
}
</script> </script>
<!-- TODO: Href doesn't work with query params. --> <!-- TODO: Href doesn't work with query params. -->
<!-- Michael J - 16 June 2025 - Accordion mode is untested. -->
{#if displayMode === 'accordion'} {#if displayMode === 'accordion'}
<Accordion multiple> <Accordion multiple>
{#each entries as entry} {#each entries as entry}
@ -79,7 +75,14 @@
{#each entries as entry} {#each entries as entry}
{@const address = entry.address} {@const address = entry.address}
{@const expanded = toc.expandedMap.get(address) ?? false} {@const expanded = toc.expandedMap.get(address) ?? false}
{#if entry.children.length > 0} {@const isLeaf = toc.leaves.has(address)}
{#if isLeaf}
<!-- TODO: Add href -->
<SidebarItem
label={entry.title}
onclick={() => onSectionFocused?.(address)}
/>
{:else}
{@const childDepth = depth + 1} {@const childDepth = depth + 1}
<SidebarDropdownWrapper <SidebarDropdownWrapper
label={entry.title} label={entry.title}
@ -95,12 +98,6 @@
onSectionFocused={onSectionFocused} onSectionFocused={onSectionFocused}
/> />
</SidebarDropdownWrapper> </SidebarDropdownWrapper>
{:else}
<!-- TODO: Add href -->
<SidebarItem
label={entry.title}
onclick={() => handleEntryClick(address, !expanded)}
/>
{/if} {/if}
{/each} {/each}
</SidebarGroup> </SidebarGroup>

18
src/lib/components/publications/table_of_contents.svelte.ts

@ -1,4 +1,4 @@
import { SvelteMap } from 'svelte/reactivity'; import { SvelteMap, SvelteSet } from 'svelte/reactivity';
import { SveltePublicationTree } from './svelte_publication_tree.svelte.ts'; import { SveltePublicationTree } from './svelte_publication_tree.svelte.ts';
import type { NDKEvent } from '../../utils/nostrUtils.ts'; import type { NDKEvent } from '../../utils/nostrUtils.ts';
import { indexKind } from '../../consts.ts'; import { indexKind } from '../../consts.ts';
@ -24,6 +24,7 @@ export interface TocEntry {
export class TableOfContents { export class TableOfContents {
public addressMap: SvelteMap<string, TocEntry> = new SvelteMap(); public addressMap: SvelteMap<string, TocEntry> = new SvelteMap();
public expandedMap: SvelteMap<string, boolean> = new SvelteMap(); public expandedMap: SvelteMap<string, boolean> = new SvelteMap();
public leaves: SvelteSet<string> = new SvelteSet();
#root: TocEntry | null = null; #root: TocEntry | null = null;
#publicationTree: SveltePublicationTree; #publicationTree: SveltePublicationTree;
@ -186,6 +187,13 @@ export class TableOfContents {
continue; continue;
} }
// Michael J - 16 June 2025 - This duplicates logic in the outer function, but is necessary
// here so that we can determine whether to render an entry as a leaf before it is fully
// resolved.
if (childAddress.split(':')[0] !== indexKind.toString()) {
this.leaves.add(childAddress);
}
// Michael J - 05 June 2025 - The `getChildAddresses` method forces node resolution on the // Michael J - 05 June 2025 - The `getChildAddresses` method forces node resolution on the
// publication tree. This is acceptable here, because the tree is always resolved // publication tree. This is acceptable here, because the tree is always resolved
// top-down. Therefore, by the time we handle a node's resolution, its parent and // top-down. Therefore, by the time we handle a node's resolution, its parent and
@ -217,6 +225,14 @@ export class TableOfContents {
resolveChildren: resolver, resolveChildren: resolver,
}; };
this.expandedMap.set(address, false); this.expandedMap.set(address, false);
// Michael J - 16 June 2025 - We determine whether to add a leaf both here and in the inner
// resolver function. The resolver function is called when entries are resolved by expanding
// a ToC entry, and we'll reach the block below when entries are resolved by the publication
// tree.
if (event.kind !== indexKind) {
this.leaves.add(address);
}
return entry; return entry;
} }

Loading…
Cancel
Save