Browse Source

Get rendering to work properly with new loader

Load-on-scroll can stand to be improved, but it works at a basic level.  Event content is rendered correctly, with headings, and many content block types have proper styling.
master
buttercat1791 11 months ago
parent
commit
1ecc6bccbd
  1. 107
      src/app.css
  2. 40
      src/lib/components/PublicationSection.svelte
  3. 12
      src/lib/snippets/PublicationSnippets.svelte

107
src/app.css

@ -186,11 +186,6 @@
@apply bg-gray-200 dark:bg-gray-700; @apply bg-gray-200 dark:bg-gray-700;
} }
/* Unordered list */
.ul-leather li a {
@apply text-gray-800 hover:text-primary-400 dark:text-gray-300 dark:hover:text-primary-500;
}
/* Network visualization */ /* Network visualization */
.network-link-leather { .network-link-leather {
@apply stroke-gray-400 fill-gray-400; @apply stroke-gray-400 fill-gray-400;
@ -203,6 +198,43 @@
} }
} }
/* Utilities can be applied via the @apply directive. */
@layer utilities {
.h-leather {
@apply text-gray-800 dark:text-gray-300 pt-4;
}
.h1-leather {
@apply text-4xl font-bold;
}
.h2-leather {
@apply text-3xl font-bold;
}
.h3-leather {
@apply text-2xl font-bold;
}
.h4-leather {
@apply text-xl font-bold;
}
.h5-leather {
@apply text-lg font-semibold;
}
.h6-leather {
@apply text-base font-semibold;
}
/* Lists */
.ol-leather li a,
.ul-leather li a {
@apply text-gray-800 hover:text-primary-400 dark:text-gray-300 dark:hover:text-primary-500;
}
}
@layer components { @layer components {
/* Legend */ /* Legend */
.leather-legend { .leather-legend {
@ -223,4 +255,69 @@
.leather-legend button { .leather-legend button {
@apply dark:text-white; @apply dark:text-white;
} }
/* Rendered publication content */
.publication-leather {
@apply flex flex-col space-y-4;
h1, h2, h3, h4, h5, h6 {
@apply h-leather;
}
h1 {
@apply h1-leather;
}
h2 {
@apply h2-leather;
}
h3 {
@apply h3-leather;
}
h4 {
@apply h4-leather;
}
h5 {
@apply h5-leather;
}
h6 {
@apply h6-leather;
}
div {
@apply flex flex-col space-y-4;
}
.olist {
@apply flex flex-col space-y-4;
ol {
@apply ol-leather list-decimal px-6 flex flex-col space-y-2;
li {
.paragraph {
@apply py-2;
}
}
}
}
.ulist {
@apply flex flex-col space-y-4;
ul {
@apply ul-leather list-disc px-6 flex flex-col space-y-2;
li {
.paragraph {
@apply py-2;
}
}
}
}
}
} }

40
src/lib/components/PublicationSection.svelte

@ -5,6 +5,7 @@
import { TextPlaceholder } from "flowbite-svelte"; import { TextPlaceholder } from "flowbite-svelte";
import { getContext } from "svelte"; import { getContext } from "svelte";
import type { Asciidoctor, Document } from "asciidoctor"; import type { Asciidoctor, Document } from "asciidoctor";
let { let {
address, address,
rootAddress, rootAddress,
@ -20,7 +21,7 @@
const publicationTree: PublicationTree = getContext('publicationTree'); const publicationTree: PublicationTree = getContext('publicationTree');
const asciidoctor: Asciidoctor = getContext('asciidoctor'); const asciidoctor: Asciidoctor = getContext('asciidoctor');
let leafEvent: Promise<NDKEvent | null> = $derived.by(async () => let leafEvent: Promise<NDKEvent | null> = $derived.by(async () =>
await publicationTree.getEvent(address)); await publicationTree.getEvent(address));
let rootEvent: Promise<NDKEvent | null> = $derived.by(async () => let rootEvent: Promise<NDKEvent | null> = $derived.by(async () =>
await publicationTree.getEvent(rootAddress)); await publicationTree.getEvent(rootAddress));
@ -28,6 +29,8 @@
(await rootEvent)?.getMatchingTags('type')[0]?.[1]); (await rootEvent)?.getMatchingTags('type')[0]?.[1]);
let leafHierarchy: Promise<NDKEvent[]> = $derived.by(async () => let leafHierarchy: Promise<NDKEvent[]> = $derived.by(async () =>
await publicationTree.getHierarchy(address)); await publicationTree.getHierarchy(address));
let leafTitle: Promise<string | undefined> = $derived.by(async () =>
(await leafEvent)?.getMatchingTags('title')[0]?.[1]);
let leafContent: Promise<string | Document> = $derived.by(async () => let leafContent: Promise<string | Document> = $derived.by(async () =>
asciidoctor.convert((await leafEvent)?.content ?? '')); asciidoctor.convert((await leafEvent)?.content ?? ''));
@ -39,40 +42,40 @@
return leaves[index - 1]; return leaves[index - 1];
}); });
let previousLeafHierarchy: Promise<NDKEvent[] | null> = $derived.by(async () => { let previousLeafHierarchy: Promise<NDKEvent[] | null> = $derived.by(async () => {
const previousLeaf = await previousLeafEvent; console.debug('Finding previous leaf hierarchy for ', address);
if (!previousLeaf) { if (!previousLeafEvent) {
return null; return null;
} }
return await publicationTree.getHierarchy(previousLeafEvent?.tagAddress() ?? '') return await publicationTree.getHierarchy(previousLeafEvent.tagAddress());
}); });
let divergingBranches = $derived.by(async () => { let divergingBranches = $derived.by(async () => {
const currentHierarchy = await leafHierarchy; console.debug('Finding diverging branches for ', address);
const previousHierarchy = await previousLeafHierarchy; let [leafHierarchyValue, previousLeafHierarchyValue] = await Promise.all([leafHierarchy, previousLeafHierarchy]);
const branches: [NDKEvent, number][] = []; const branches: [NDKEvent, number][] = [];
if (!previousHierarchy) { if (!previousLeafHierarchyValue) {
for (let i = 0; i < currentHierarchy.length - 1; i++) { for (let i = 0; i < leafHierarchyValue.length - 1; i++) {
branches.push([currentHierarchy[i], i]); branches.push([leafHierarchyValue[i], i]);
} }
return branches; return branches;
} }
const minLength = Math.min(currentHierarchy.length, previousHierarchy.length); const minLength = Math.min(leafHierarchyValue.length, previousLeafHierarchyValue.length);
// Find the first diverging node. // Find the first diverging node.
let divergingIndex = 0; let divergingIndex = 0;
while ( while (
divergingIndex < minLength && divergingIndex < minLength &&
currentHierarchy[divergingIndex].tagAddress() === previousHierarchy[divergingIndex].tagAddress() leafHierarchyValue[divergingIndex].tagAddress() === previousLeafHierarchyValue[divergingIndex].tagAddress()
) { ) {
divergingIndex++; divergingIndex++;
} }
// Add all branches from the first diverging node to the current leaf. // Add all branches from the first diverging node to the current leaf.
for (let i = divergingIndex; i < currentHierarchy.length - 1; i++) { for (let i = divergingIndex; i < leafHierarchyValue.length - 1; i++) {
branches.push([currentHierarchy[i], i]); branches.push([leafHierarchyValue[i], i]);
} }
return branches; return branches;
@ -90,15 +93,18 @@
</script> </script>
<!-- TODO: Correctly handle events that are the start of a content section. --> <!-- TODO: Correctly handle events that are the start of a content section. -->
<section bind:this={sectionRef}> <section bind:this={sectionRef} class='publication-leather'>
{#await Promise.all([leafContent, publicationType, divergingBranches])} {#await Promise.all([leafTitle, leafContent, leafHierarchy, publicationType, divergingBranches])}
<TextPlaceholder size='xxl' /> <TextPlaceholder size='xxl' />
{:then [leafContent, publicationType, divergingBranches]} {:then [leafTitle, leafContent, leafHierarchy, publicationType, divergingBranches]}
<!-- TODO: Ensure we render all headings, not just the first one. --> <!-- TODO: Ensure we render all headings, not just the first one. -->
{#each divergingBranches as [branch, depth]} {#each divergingBranches as [branch, depth]}
{@render sectionHeading(branch.getMatchingTags('title')[0]?.[1] ?? '', depth)} {@render sectionHeading(branch.getMatchingTags('title')[0]?.[1] ?? '', depth)}
{/each} {/each}
{#if leafTitle}
{@const leafDepth = leafHierarchy.length - 1}
{@render sectionHeading(leafTitle, leafDepth)}
{/if}
{@render contentParagraph(leafContent.toString(), publicationType ?? 'article', false)} {@render contentParagraph(leafContent.toString(), publicationType ?? 'article', false)}
{/await} {/await}
</section> </section>

12
src/lib/snippets/PublicationSnippets.svelte

@ -14,13 +14,7 @@
{/snippet} {/snippet}
{#snippet contentParagraph(content: string, publicationType: string, isSectionStart: boolean)} {#snippet contentParagraph(content: string, publicationType: string, isSectionStart: boolean)}
{#if publicationType === 'novel'} <section class='whitespace-normal publication-leather'>
<P class='whitespace-normal' firstupper={isSectionStart}> {@html content}
{@html content} </section>
</P>
{:else}
<P class='whitespace-normal' firstupper={false}>
{@html content}
</P>
{/if}
{/snippet} {/snippet}

Loading…
Cancel
Save