Support resources with kind:30023 articles
This commit is contained in:
parent
f6bea700f0
commit
b901215e1a
13 changed files with 285 additions and 75 deletions
|
|
@ -1,8 +1,19 @@
|
|||
<script lang="ts">
|
||||
import { overviewStore } from "$lib/overview.svelte";
|
||||
import { overviewStore, loadOverview } from "$lib/overview.svelte";
|
||||
import { groupsStore } from "$lib/groups.svelte";
|
||||
import { MODE, GROUP_ID } from "$lib/config";
|
||||
import type { NostrUser } from "@nostr/gadgets/metadata";
|
||||
|
||||
// Self-load so the panel works wherever it's mounted (home, article pages).
|
||||
// Simple mode has the single configured group; full mode spans every room.
|
||||
// loadOverview dedupes on the room-id set, so this is safe alongside the
|
||||
// landing page's own call.
|
||||
$effect(() => {
|
||||
const ids =
|
||||
MODE === "full" ? groupsStore.list.map((g) => g.id) : [GROUP_ID];
|
||||
if (ids.length > 0) loadOverview(ids);
|
||||
});
|
||||
|
||||
function roomName(id: string) {
|
||||
return groupsStore.list.find((g) => g.id === id)?.name ?? id;
|
||||
}
|
||||
|
|
@ -51,8 +62,10 @@
|
|||
{author.name[0].toUpperCase()}
|
||||
</span>
|
||||
{/if}
|
||||
<span aria-hidden="true">in</span>
|
||||
<span class="truncate">{roomName(t.groupId)}</span>
|
||||
{#if MODE === "full"}
|
||||
<span aria-hidden="true">in</span>
|
||||
<span class="truncate">{roomName(t.groupId)}</span>
|
||||
{/if}
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { auth, openLogin, logout } from "$lib/auth.svelte";
|
||||
import { groupStore } from "$lib/group.svelte";
|
||||
import { groupsStore } from "$lib/groups.svelte";
|
||||
import { resourcesStore } from "$lib/resources.svelte";
|
||||
import { draftState, resumeDraft } from "$lib/draft.svelte";
|
||||
|
||||
type Props = {
|
||||
|
|
@ -54,27 +55,33 @@
|
|||
</nav>
|
||||
{#if activeAbout}
|
||||
<div class="mt-6">
|
||||
<p
|
||||
class="pb-1 text-xs font-semibold uppercase tracking-wider text-neutral-400"
|
||||
>
|
||||
About
|
||||
</p>
|
||||
<p class="text-sm text-neutral-500">{activeAbout}</p>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<nav class="flex-auto mt-6">
|
||||
<div class="">
|
||||
<p
|
||||
class="pb-1 text-xs font-semibold uppercase tracking-wider text-neutral-400"
|
||||
>
|
||||
More
|
||||
</p>
|
||||
<nav class="flex-auto mt-6" aria-label="Resources">
|
||||
<p
|
||||
class="pb-1 text-xs font-semibold uppercase tracking-wider text-neutral-400"
|
||||
>
|
||||
Resources
|
||||
</p>
|
||||
{#each resourcesStore.list as r (r.slug)}
|
||||
<a
|
||||
href="/about"
|
||||
class="block py-1 text-neutral-500 hover:text-neutral-900">About</a
|
||||
href="/resource/{r.slug}"
|
||||
class="block py-1 text-neutral-500 hover:text-neutral-900"
|
||||
>{r.title}</a
|
||||
>
|
||||
<a
|
||||
href="/contacts"
|
||||
class="block py-1 text-neutral-500 hover:text-neutral-900">Contacts</a
|
||||
>
|
||||
</div>
|
||||
{/each}
|
||||
<a
|
||||
href="/contacts"
|
||||
class="block py-1 text-neutral-500 hover:text-neutral-900">Contacts</a
|
||||
>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { fly, fade } from "svelte/transition";
|
||||
import { groupsStore } from "$lib/groups.svelte";
|
||||
import { resourcesStore } from "$lib/resources.svelte";
|
||||
import { auth, openLogin, logout } from "$lib/auth.svelte";
|
||||
import { draftState, resumeDraft } from "$lib/draft.svelte";
|
||||
|
||||
|
|
@ -115,7 +116,7 @@
|
|||
{#if mode === "full"}
|
||||
<nav class="mt-4" aria-label="Rooms">
|
||||
<p
|
||||
class="pb-1 text-xs font-semibold uppercase tracking-wider text-neutral-400"
|
||||
class="pb-1 font-semibold uppercase tracking-wider text-neutral-400"
|
||||
>
|
||||
Rooms
|
||||
</p>
|
||||
|
|
@ -126,7 +127,7 @@
|
|||
<a
|
||||
href="/room/{room.id}"
|
||||
onclick={onClose}
|
||||
class="block py-1.5 text-lg
|
||||
class="block py-1.5 text-xl
|
||||
{activeRoom === room.id ? 'text-brand' : 'text-neutral-700 hover:text-brand'}"
|
||||
>
|
||||
{room.name}
|
||||
|
|
@ -135,16 +136,27 @@
|
|||
</nav>
|
||||
{/if}
|
||||
|
||||
<a
|
||||
href="/about"
|
||||
onclick={onClose}
|
||||
class="py-2 text-xl text-neutral-700 hover:text-brand">About</a
|
||||
>
|
||||
<a
|
||||
href="/contacts"
|
||||
onclick={onClose}
|
||||
class="py-2 text-xl text-neutral-700 hover:text-brand">Contacts</a
|
||||
>
|
||||
<nav class="mt-4" aria-label="Resources">
|
||||
<p
|
||||
class="pb-1 font-semibold uppercase tracking-wider text-neutral-400"
|
||||
>
|
||||
Resources
|
||||
</p>
|
||||
{#each resourcesStore.list as r (r.slug)}
|
||||
<a
|
||||
href="/resource/{r.slug}"
|
||||
onclick={onClose}
|
||||
class="block py-1.5 text-xl text-neutral-700 hover:text-brand"
|
||||
>{r.title}</a
|
||||
>
|
||||
{/each}
|
||||
<a
|
||||
href="/contacts"
|
||||
onclick={onClose}
|
||||
class="block py-1.5 text-lg text-neutral-700 hover:text-brand"
|
||||
>Contacts</a
|
||||
>
|
||||
</nav>
|
||||
|
||||
<div class="mt-4 flex flex-col gap-2 border-t border-neutral-100 pt-4">
|
||||
{#if draftState.iconized}
|
||||
|
|
@ -177,9 +189,12 @@
|
|||
{auth.user.shortName.slice(0, 1).toUpperCase()}
|
||||
</span>
|
||||
{/if}
|
||||
<span class="truncate text-lg font-medium">{auth.user.shortName}</span
|
||||
<span class="truncate text-lg font-medium"
|
||||
>{auth.user.shortName}</span
|
||||
>
|
||||
<span class="ml-auto shrink-0 text-sm text-neutral-400"
|
||||
>Log out</span
|
||||
>
|
||||
<span class="ml-auto shrink-0 text-sm text-neutral-400">Log out</span>
|
||||
</button>
|
||||
{:else}
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
<script lang="ts">
|
||||
import { groupStore } from "$lib/group.svelte";
|
||||
import { GROUP_ID, TITLE } from "$lib/config";
|
||||
import { GROUP_ID, TITLE, MODE } from "$lib/config";
|
||||
|
||||
type Props = { onMenuToggle: () => void };
|
||||
let { onMenuToggle }: Props = $props();
|
||||
|
||||
const name = $derived(TITLE || groupStore.data?.name || GROUP_ID);
|
||||
// PUBLIC_TITLE always wins when set. Without it, simple mode shows the room's
|
||||
// own name; full mode has no single room, so it falls back to GROUP_ID.
|
||||
const name = $derived(
|
||||
TITLE || (MODE === "simple" ? (groupStore.data?.name ?? GROUP_ID) : GROUP_ID),
|
||||
);
|
||||
</script>
|
||||
|
||||
<header
|
||||
|
|
|
|||
|
|
@ -15,9 +15,18 @@
|
|||
content: string;
|
||||
profiles?: Record<string, NostrUser>;
|
||||
threadEventAuthors?: Record<string, string>;
|
||||
// Added to each heading level. Thread posts demote by 1 (the post title is
|
||||
// a separate h1, so content headings start at h2); standalone articles
|
||||
// pass 0 to keep their real levels.
|
||||
headingOffset?: number;
|
||||
};
|
||||
|
||||
let { content, profiles = {}, threadEventAuthors = {} }: Props = $props();
|
||||
let {
|
||||
content,
|
||||
profiles = {},
|
||||
threadEventAuthors = {},
|
||||
headingOffset = 1,
|
||||
}: Props = $props();
|
||||
|
||||
// Curated TLD list: gTLDs, popular new gTLDs, common ccTLDs
|
||||
const TLDS = [
|
||||
|
|
@ -675,7 +684,7 @@
|
|||
{@render renderBlocks(block.blocks)}
|
||||
</blockquote>
|
||||
{:else if block.type === "heading"}
|
||||
{@const tag = `h${Math.min(block.level + 2, 6)}`}
|
||||
{@const tag = `h${Math.max(1, Math.min(block.level + headingOffset, 6))}`}
|
||||
<svelte:element this={tag}>
|
||||
{@render renderInlines(block.inlines)}
|
||||
</svelte:element>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue