Browse Source

More dynamic and reactive columns

master
Nuša Pukšič 10 months ago
parent
commit
1a537239ed
  1. 3
      src/app.css
  2. 34
      src/lib/components/Publication.svelte
  3. 11
      src/lib/components/blog/BlogHeader.svelte
  4. 43
      src/lib/components/util/ArticleNav.svelte
  5. 2
      src/lib/components/util/Interactions.svelte

3
src/app.css

@ -60,7 +60,7 @@
/* To scroll columns independently */ /* To scroll columns independently */
main.publication.blog { main.publication.blog {
@apply min-h-full; @apply w-full sm:w-auto min-h-full;
max-height: calc(100vh - 146px); max-height: calc(100vh - 146px);
} }
@ -380,7 +380,6 @@
.line-ellipsis { .line-ellipsis {
max-width: 100%; max-width: 100%;
white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }

34
src/lib/components/Publication.svelte

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { import {
Button, Button, Card, Img,
Sidebar, Sidebar,
SidebarGroup, SidebarGroup,
SidebarItem, SidebarItem,
@ -68,6 +68,7 @@
// #endregion // #endregion
let currentBlog: null|string = $state(null); let currentBlog: null|string = $state(null);
let currentBlogEvent: null|NDKEvent = $state(null);
function isDefaultVisible() { function isDefaultVisible() {
if (publicationType !== 'blog') { if (publicationType !== 'blog') {
@ -81,18 +82,26 @@
return currentBlog !== null && $publicationColumnVisibility.inner; return currentBlog !== null && $publicationColumnVisibility.inner;
} }
function isSocialActive() {
return $publicationColumnVisibility.social;
}
function loadBlog(rootId: string) { function loadBlog(rootId: string) {
// depending on the size of the screen, also toggle blog list visibility // depending on the size of the screen, also toggle blog list & social visibility
if (window.innerWidth < 1024) { if (window.innerWidth < 1024) {
$publicationColumnVisibility.blog = false; $publicationColumnVisibility.blog = false;
$publicationColumnVisibility.social = false;
} }
$publicationColumnVisibility.inner = true; $publicationColumnVisibility.inner = true;
currentBlog = rootId; currentBlog = rootId;
// set current blog values for publication render // set current blog values for publication render
console.log(currentBlog); currentBlogEvent = leaves.find(i => i.tagAddress() === currentBlog) ?? null;
} }
function showBlogHeaderOnMobile() {
return (currentBlog && currentBlogEvent && window.innerWidth < 1024);
}
onMount(() => { onMount(() => {
// Set up the intersection observer. // Set up the intersection observer.
@ -162,8 +171,25 @@
{/key} {/key}
{/if} {/if}
{#if $publicationColumnVisibility.social } {#if isSocialActive() }
<div class="flex flex-col p-4 space-y-4 max-w-xl overflow-auto flex-grow-1"> <div class="flex flex-col p-4 space-y-4 max-w-xl overflow-auto flex-grow-1">
{#if showBlogHeaderOnMobile()}
<BlogHeader
rootId={currentBlog}
event={currentBlogEvent}
onBlogUpdate={loadBlog}
active={true}
/>
{/if}
<div class="flex flex-col w-full">
<Card class="ArticleBox card-leather w-full grid max-w-xl">
<div class='space-y-2'>
<div class='flex flex-col flex-grow space-y-4'>
This is a placeholder comment...
</div>
</div>
</Card>
</div>
</div> </div>
{/if} {/if}

11
src/lib/components/blog/BlogHeader.svelte

@ -1,12 +1,12 @@
<script lang="ts"> <script lang="ts">
import type { NDKEvent } from '@nostr-dev-kit/ndk'; import type { NDKEvent } from '@nostr-dev-kit/ndk';
import { scale } from 'svelte/transition'; import { scale } from 'svelte/transition';
import { Button, Card, Img } from "flowbite-svelte"; import { Card, Img } from "flowbite-svelte";
import InlineProfile from "$components/util/InlineProfile.svelte"; import InlineProfile from "$components/util/InlineProfile.svelte";
import Interactions from "$components/util/Interactions.svelte"; import Interactions from "$components/util/Interactions.svelte";
import { quintOut } from "svelte/easing"; import { quintOut } from "svelte/easing";
const { rootId, event, onBlogUpdate, active = true } = $props<{ rootId: String, event: NDKEvent, onBlogUpdate?: any, active: boolean }>(); const { rootId, event, onBlogUpdate, active = true } = $props<{ rootId: string, event: NDKEvent, onBlogUpdate?: any, active: boolean }>();
let title: string = $derived(event.getMatchingTags('title')[0]?.[1]); let title: string = $derived(event.getMatchingTags('title')[0]?.[1]);
let author: string = $derived(event.getMatchingTags('author')[0]?.[1] ?? 'unknown'); let author: string = $derived(event.getMatchingTags('author')[0]?.[1] ?? 'unknown');
@ -33,7 +33,7 @@
{#if title != null} {#if title != null}
<Card class="ArticleBox card-leather w-full grid max-w-xl {active ? 'active' : ''}"> <Card class="ArticleBox card-leather w-full grid max-w-xl {active ? 'active' : ''}">
<div class='space-y-2'> <div class='space-y-4'>
<div class="flex flex-row justify-between my-2"> <div class="flex flex-row justify-between my-2">
<InlineProfile pubkey={authorPubkey} title={author} /> <InlineProfile pubkey={authorPubkey} title={author} />
<span class='text-gray-500'>{publishedAt()}</span> <span class='text-gray-500'>{publishedAt()}</span>
@ -49,12 +49,9 @@
<button onclick={() => showBlog()} class='text-left'> <button onclick={() => showBlog()} class='text-left'>
<h2 class='text-lg font-bold line-clamp-2' title="{title}">{title}</h2> <h2 class='text-lg font-bold line-clamp-2' title="{title}">{title}</h2>
</button> </button>
{#if active}
<Button color="none" class="underline justify-end p-0" onclick={() => showBlog()} ><span class="">Read all about it...</span></Button>
{/if}
</div> </div>
{#if active} {#if active}
<div class='flex flex-row '> <div class='flex flex-row'>
<Interactions rootId={rootId} event={event} /> <Interactions rootId={rootId} event={event} />
</div> </div>
{/if} {/if}

43
src/lib/components/util/ArticleNav.svelte

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import TocToggle from "$components/util/TocToggle.svelte"; import TocToggle from "$components/util/TocToggle.svelte";
import { BookOutline, CaretLeftOutline } from "flowbite-svelte-icons"; import { BookOutline, CaretLeftOutline, GlobeOutline } from "flowbite-svelte-icons";
import { Button } from "flowbite-svelte"; import { Button } from "flowbite-svelte";
import { publicationColumnVisibility } from "$lib/stores"; import { publicationColumnVisibility } from "$lib/stores";
import InlineProfile from "$components/util/InlineProfile.svelte"; import InlineProfile from "$components/util/InlineProfile.svelte";
@ -13,7 +13,8 @@
} = $props<{ } = $props<{
rootId: any, rootId: any,
publicationType: string, publicationType: string,
indexEvent: NDKEvent indexEvent: NDKEvent,
blogEvent: NDKEvent|null
}>(); }>();
let title: string = $derived(indexEvent.getMatchingTags('title')[0]?.[1]); let title: string = $derived(indexEvent.getMatchingTags('title')[0]?.[1]);
@ -24,7 +25,10 @@
function toggleColumn(column: 'blog'|'inner'|'social') { function toggleColumn(column: 'blog'|'inner'|'social') {
publicationColumnVisibility.update(store => { publicationColumnVisibility.update(store => {
store[column] = !store[column]; // Toggle true/false store[column] = !store[column]; // Toggle true/false
if (window.innerWidth < 1140) { if (window.innerWidth < 1400 && $publicationColumnVisibility.social) {
$publicationColumnVisibility.blog = false;
}
if (window.innerWidth < 1200) {
$publicationColumnVisibility.inner = false; $publicationColumnVisibility.inner = false;
} }
return { ...store }; // Ensure reactivity return { ...store }; // Ensure reactivity
@ -32,32 +36,51 @@
} }
function backToMain() { function backToMain() {
if ($publicationColumnVisibility.social) {
$publicationColumnVisibility.inner = true;
$publicationColumnVisibility.social = false;
} else {
$publicationColumnVisibility.blog = true; $publicationColumnVisibility.blog = true;
$publicationColumnVisibility.inner = false; $publicationColumnVisibility.inner = false;
$publicationColumnVisibility.social = false;
}
} }
</script> </script>
<nav class="Navbar navbar-leather flex sticky top-[76px] w-full min-h-[70px] px-2 sm:px-4 py-2.5 z-10"> <nav class="Navbar navbar-leather flex sticky top-[76px] w-full min-h-[70px] px-2 sm:px-4 py-2.5 z-10">
<div class="flex flex-wrap space-x-2 container"> <div class="mx-auto flex space-x-2 container">
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2 md:min-w-52 min-w-8">
{#if publicationType === 'blog'} {#if publicationType === 'blog'}
{#if $publicationColumnVisibility.inner} {#if $publicationColumnVisibility.inner || $publicationColumnVisibility.social}
<Button class='btn-leather !w-auto' outline={true} onclick={backToMain}> <Button class='btn-leather !w-auto sm:hidden' outline={true} onclick={backToMain}>
<CaretLeftOutline class="!fill-none inline mr-1" /><span class="hidden sm:inline">Back</span> <CaretLeftOutline class="!fill-none inline mr-1" /><span class="hidden sm:inline">Back</span>
</Button> </Button>
{/if} {/if}
<Button class="btn-leather !w-auto {$publicationColumnVisibility.blog ? 'active' : ''}" <Button class="btn-leather hidden sm:flex !w-auto {$publicationColumnVisibility.blog ? 'active' : ''}"
outline={true} onclick={() => toggleColumn('blog')} > outline={true} onclick={() => toggleColumn('blog')} >
<BookOutline class="!fill-none inline mr-1" /><span class="hidden sm:inline">Table of Contents</span> <BookOutline class="!fill-none inline mr-1" /><span class="hidden sm:inline">Table of Contents</span>
</Button> </Button>
{:else} {:else}
<TocToggle rootId={rootId} /> <TocToggle rootId={rootId} />
{/if} {/if}
</div> </div>
<div class="flex text items-center"> <div class="flex flex-grow text justify-center items-center">
<p class="line-ellipsis"><b>{title}</b> <span>by <InlineProfile pubkey={pubkey} title={author} /></span></p> <p class="line-ellipsis"><b>{title}</b> <span>by <InlineProfile pubkey={pubkey} title={author} /></span></p>
</div> </div>
<div class="flex items-center space-x-2 md:min-w-52 min-w-8">
{#if publicationType === 'blog'}
{#if $publicationColumnVisibility.inner || $publicationColumnVisibility.social}
<Button class='btn-leather !w-auto hidden sm:flex' outline={true} onclick={backToMain}>
<CaretLeftOutline class="!fill-none inline mr-1" /><span class="hidden sm:inline">Back</span>
</Button>
{/if}
{#if $publicationColumnVisibility.inner}
<Button class='btn-leather !w-auto' outline={true} onclick={() => toggleColumn('social')}>
<GlobeOutline class="!fill-none inline mr-1" /><span class="hidden sm:inline">Social</span>
</Button>
{/if}
{/if}
</div>
</div> </div>
</nav> </nav>

2
src/lib/components/util/Interactions.svelte

@ -5,7 +5,7 @@
import { onMount } from "svelte"; import { onMount } from "svelte";
import { ndkInstance } from '$lib/ndk'; import { ndkInstance } from '$lib/ndk';
const { rootId, event } = $props<{ rootId: String, event: NDKEvent }>(); const { rootId, event } = $props<{ rootId: string, event: NDKEvent }>();
// Reactive arrays to hold incoming events // Reactive arrays to hold incoming events
let likes: NDKEvent[] = []; let likes: NDKEvent[] = [];

Loading…
Cancel
Save