Tweak layout css
This commit is contained in:
parent
d94860014c
commit
ad034b1641
12 changed files with 410 additions and 368 deletions
14
src/app.css
14
src/app.css
|
|
@ -338,18 +338,14 @@ progress[value]::-webkit-progress-value {
|
|||
@apply w-full md:w-[calc(100%-18.5rem)];
|
||||
}
|
||||
|
||||
.cb {
|
||||
@apply saib bottom-14 md:bottom-0;
|
||||
}
|
||||
|
||||
/* chat view */
|
||||
|
||||
.chat__page-bar {
|
||||
@apply sait cw !fixed top-2;
|
||||
}
|
||||
|
||||
.chat__messages {
|
||||
@apply saib cw fixed top-12 flex h-[calc(100%-6.5rem)] flex-col-reverse overflow-y-auto overflow-x-hidden md:h-[calc(100%-3rem)];
|
||||
}
|
||||
|
||||
.chat__compose {
|
||||
@apply saib cw fixed bottom-14 md:bottom-0;
|
||||
@apply cb cw fixed;
|
||||
}
|
||||
|
||||
.chat__scroll-down {
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@
|
|||
const content = initialValues?.content || ""
|
||||
const editor = makeEditor({submit, uploading, content})
|
||||
|
||||
let title = $state(initialValues?.title)
|
||||
let location = $state(initialValues?.location)
|
||||
let title = $state(initialValues?.title || "")
|
||||
let location = $state(initialValues?.location || "")
|
||||
let start: number | undefined = $state(initialValues?.start)
|
||||
let end: number | undefined = $state(initialValues?.end)
|
||||
let endDirty = Boolean(initialValues?.end)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
import Link from "@lib/components/Link.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import PageBar from "@lib/components/PageBar.svelte"
|
||||
import PageContent from "@lib/components/PageContent.svelte"
|
||||
import Divider from "@lib/components/Divider.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import ProfileName from "@app/components/ProfileName.svelte"
|
||||
|
|
@ -124,7 +125,7 @@
|
|||
</script>
|
||||
|
||||
{#if others.length > 0}
|
||||
<PageBar class="chat__page-bar">
|
||||
<PageBar>
|
||||
{#snippet title()}
|
||||
<div class="flex flex-col gap-1 sm:flex-row sm:gap-2">
|
||||
{#if others.length === 1}
|
||||
|
|
@ -172,7 +173,7 @@
|
|||
</PageBar>
|
||||
{/if}
|
||||
|
||||
<div class="chat__messages scroll-container">
|
||||
<PageContent class="flex flex-col-reverse pt-4">
|
||||
<div bind:this={dynamicPadding}></div>
|
||||
{#if missingInboxes.includes($pubkey!)}
|
||||
<div class="py-12">
|
||||
|
|
@ -223,7 +224,7 @@
|
|||
</Spinner>
|
||||
{@render info?.()}
|
||||
</p>
|
||||
</div>
|
||||
</PageContent>
|
||||
|
||||
<div class="chat__compose bg-base-200" bind:this={chatCompose}>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<script lang="ts">
|
||||
import {onMount} from "svelte"
|
||||
import {writable} from "svelte/store"
|
||||
import {isMobile, preventDefault} from "@lib/html"
|
||||
import {fly, slideAndFade} from "@lib/transition"
|
||||
import {fly} from "@lib/transition"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
|
|
@ -32,13 +33,34 @@
|
|||
}
|
||||
|
||||
const editor = makeEditor({submit, uploading, autofocus: !isMobile})
|
||||
|
||||
let form: HTMLElement
|
||||
let spacer: HTMLElement
|
||||
|
||||
onMount(() => {
|
||||
setTimeout(() => {
|
||||
spacer.scrollIntoView({block: "end", behavior: "smooth"})
|
||||
})
|
||||
|
||||
const observer = new ResizeObserver(() => {
|
||||
spacer!.style.minHeight = `${form!.offsetHeight}px`
|
||||
})
|
||||
|
||||
observer.observe(form!)
|
||||
|
||||
return () => {
|
||||
observer.unobserve(form!)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<div bind:this={spacer}></div>
|
||||
<form
|
||||
in:fly
|
||||
out:slideAndFade
|
||||
bind:this={form}
|
||||
onsubmit={preventDefault(submit)}
|
||||
class="card2 sticky bottom-2 z-feature mx-2 mt-4 bg-neutral">
|
||||
class="cb cw fixed z-feature -mx-2 pt-3">
|
||||
<div class="card2 mx-2 my-2 bg-neutral">
|
||||
<div class="relative">
|
||||
<div class="note-editor flex-grow overflow-hidden">
|
||||
<EditorContent {editor} />
|
||||
|
|
@ -58,4 +80,5 @@
|
|||
<Button class="btn btn-link" onclick={onClose}>Cancel</Button>
|
||||
<Button type="submit" class="btn btn-primary">Post Reply</Button>
|
||||
</ModalFooter>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
<script lang="ts">
|
||||
import type {Snippet} from "svelte"
|
||||
|
||||
interface Props {
|
||||
icon?: import("svelte").Snippet
|
||||
title?: import("svelte").Snippet
|
||||
action?: import("svelte").Snippet
|
||||
icon?: Snippet
|
||||
title?: Snippet
|
||||
action?: Snippet
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
const {...props}: Props = $props()
|
||||
</script>
|
||||
|
||||
<div class="relative z-feature rounded-xl px-2 pt-2 {props.class}">
|
||||
<div class="sait cw fixed top-2 z-feature rounded-xl px-2 pt-2 {props.class}">
|
||||
<div
|
||||
class="flex min-h-12 items-center justify-between gap-4 rounded-xl bg-base-100 px-4 shadow-xl">
|
||||
<div class="ellipsize flex items-center gap-4 whitespace-nowrap">
|
||||
|
|
|
|||
18
src/lib/components/PageContent.svelte
Normal file
18
src/lib/components/PageContent.svelte
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<script lang="ts">
|
||||
import type {Snippet} from "svelte"
|
||||
|
||||
interface Props {
|
||||
element?: Element
|
||||
children?: Snippet
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
let {children, element = $bindable(), ...props}: Props = $props()
|
||||
</script>
|
||||
|
||||
<div
|
||||
{...props}
|
||||
bind:this={element}
|
||||
class="scroll-container saib cw fixed top-12 h-[calc(100%-6.5rem)] overflow-y-auto overflow-x-hidden md:h-[calc(100%-3rem)] {props.class}">
|
||||
{@render children?.()}
|
||||
</div>
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
import Button from "@lib/components/Button.svelte"
|
||||
import Divider from "@lib/components/Divider.svelte"
|
||||
import PageBar from "@lib/components/PageBar.svelte"
|
||||
import PageContent from "@lib/components/PageContent.svelte"
|
||||
import MenuSpaceButton from "@app/components/MenuSpaceButton.svelte"
|
||||
import ProfileFeed from "@app/components/ProfileFeed.svelte"
|
||||
import ChannelName from "@app/components/ChannelName.svelte"
|
||||
|
|
@ -45,7 +46,6 @@
|
|||
const pubkey = $derived($relay?.profile?.pubkey)
|
||||
</script>
|
||||
|
||||
<div class="relative flex flex-col">
|
||||
<PageBar>
|
||||
{#snippet icon()}
|
||||
<div class="center">
|
||||
|
|
@ -72,7 +72,8 @@
|
|||
</div>
|
||||
{/snippet}
|
||||
</PageBar>
|
||||
<div class="col-2 p-2">
|
||||
|
||||
<PageContent class="flex flex-col p-2 pt-4">
|
||||
<div class="card2 bg-alt col-4 text-left">
|
||||
<div class="relative flex gap-4">
|
||||
<div class="relative">
|
||||
|
|
@ -163,8 +164,7 @@
|
|||
<ChannelName {url} {room} />
|
||||
</div>
|
||||
{#if $notifications.has(roomPath)}
|
||||
<div class="absolute right-1 top-1 h-2 w-2 rounded-full bg-primary" transition:fade>
|
||||
</div>
|
||||
<div class="absolute right-1 top-1 h-2 w-2 rounded-full bg-primary" transition:fade></div>
|
||||
{/if}
|
||||
</Link>
|
||||
{/each}
|
||||
|
|
@ -194,5 +194,4 @@
|
|||
<ProfileFeed hideLoading {url} {pubkey} bind:events={relayAdminEvents} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</PageContent>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
import Button from "@lib/components/Button.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import PageBar from "@lib/components/PageBar.svelte"
|
||||
import PageContent from "@lib/components/PageContent.svelte"
|
||||
import Divider from "@lib/components/Divider.svelte"
|
||||
import MenuSpaceButton from "@app/components/MenuSpaceButton.svelte"
|
||||
import ChannelName from "@app/components/ChannelName.svelte"
|
||||
|
|
@ -232,7 +233,7 @@
|
|||
})
|
||||
</script>
|
||||
|
||||
<PageBar class="chat__page-bar">
|
||||
<PageBar>
|
||||
{#snippet icon()}
|
||||
<div class="center">
|
||||
<Icon icon="hashtag" />
|
||||
|
|
@ -267,7 +268,7 @@
|
|||
{/snippet}
|
||||
</PageBar>
|
||||
|
||||
<div class="chat__messages scroll-container" onscroll={onScroll} bind:this={element}>
|
||||
<PageContent bind:element onscroll={onScroll} class="flex flex-col-reverse pt-4">
|
||||
<div bind:this={dynamicPadding}></div>
|
||||
{#each elements as { type, id, value, showPubkey } (id)}
|
||||
{#if type === "new-messages"}
|
||||
|
|
@ -299,7 +300,7 @@
|
|||
<Spinner>End of message history</Spinner>
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
</PageContent>
|
||||
|
||||
<div class="chat__compose bg-base-200" bind:this={chatCompose}>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
import Button from "@lib/components/Button.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import PageBar from "@lib/components/PageBar.svelte"
|
||||
import PageContent from "@lib/components/PageContent.svelte"
|
||||
import Divider from "@lib/components/Divider.svelte"
|
||||
import MenuSpaceButton from "@app/components/MenuSpaceButton.svelte"
|
||||
import CalendarEventItem from "@app/components/CalendarEventItem.svelte"
|
||||
|
|
@ -27,7 +28,7 @@
|
|||
|
||||
const getStart = (event: TrustedEvent) => parseInt(getTagValue("start", event.tags) || "")
|
||||
|
||||
let element: HTMLElement
|
||||
let element: HTMLElement | undefined = $state()
|
||||
let loading = $state(true)
|
||||
let cleanup: () => void
|
||||
let events: Readable<TrustedEvent[]> = $state(readable([]))
|
||||
|
|
@ -69,11 +70,11 @@
|
|||
if (initialScrollDone) {
|
||||
// If new events are prepended, adjust the scroll position so that the viewport content remains anchored
|
||||
if (prevFirstEventId && items[0].event.id !== prevFirstEventId) {
|
||||
const newScrollHeight = element.scrollHeight
|
||||
const newScrollHeight = element!.scrollHeight
|
||||
const delta = newScrollHeight - previousScrollHeight
|
||||
|
||||
if (delta > 0) {
|
||||
element.scrollTop += delta
|
||||
element!.scrollTop += delta
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -83,11 +84,11 @@
|
|||
) as HTMLElement
|
||||
|
||||
// On initial load, center the scroll container on today's date (or the next available event)
|
||||
element.scrollTop = offsetTop - element.clientHeight / 2 + clientHeight / 2
|
||||
element!.scrollTop = offsetTop - element!.clientHeight / 2 + clientHeight / 2
|
||||
initialScrollDone = true
|
||||
}
|
||||
|
||||
previousScrollHeight = element.scrollHeight
|
||||
previousScrollHeight = element!.scrollHeight
|
||||
prevFirstEventId = items[0].event.id
|
||||
})
|
||||
|
||||
|
|
@ -98,7 +99,7 @@
|
|||
]
|
||||
|
||||
;({events, cleanup} = makeCalendarFeed({
|
||||
element,
|
||||
element: element!,
|
||||
relays: [url],
|
||||
feedFilters,
|
||||
subscriptionFilters,
|
||||
|
|
@ -115,7 +116,6 @@
|
|||
})
|
||||
</script>
|
||||
|
||||
<div class="relative flex h-screen flex-col">
|
||||
<PageBar>
|
||||
{#snippet icon()}
|
||||
<div class="center">
|
||||
|
|
@ -135,7 +135,8 @@
|
|||
</div>
|
||||
{/snippet}
|
||||
</PageBar>
|
||||
<div class="scroll-container flex flex-grow flex-col gap-2 overflow-auto p-2" bind:this={element}>
|
||||
|
||||
<PageContent bind:element class="flex flex-col gap-2 p-2 pt-4">
|
||||
{#each items as { event, dateDisplay, isFirstFutureEvent }, i (event.id)}
|
||||
<div class={"calendar-event-" + event.id}>
|
||||
{#if isFirstFutureEvent}
|
||||
|
|
@ -160,5 +161,4 @@
|
|||
{:else}
|
||||
<p class="flex h-10 items-center justify-center py-20" transition:fly>That's all!</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</PageContent>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
import {deriveEvents} from "@welshman/store"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import PageBar from "@lib/components/PageBar.svelte"
|
||||
import PageContent from "@lib/components/PageContent.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Content from "@app/components/Content.svelte"
|
||||
|
|
@ -53,33 +54,25 @@
|
|||
})
|
||||
</script>
|
||||
|
||||
<div class="relative flex flex-col-reverse gap-3 px-2">
|
||||
<div class="absolute left-[51px] top-32 h-[calc(100%-248px)] w-[2px] bg-neutral"></div>
|
||||
<PageBar>
|
||||
{#snippet icon()}
|
||||
<div>
|
||||
<Button class="btn btn-neutral btn-sm flex-nowrap whitespace-nowrap" onclick={back}>
|
||||
<Icon icon="alt-arrow-left" />
|
||||
<span class="hidden sm:inline">Go back</span>
|
||||
</Button>
|
||||
</div>
|
||||
{/snippet}
|
||||
{#snippet title()}
|
||||
<h1 class="text-xl">{getTagValue("title", $event?.tags || []) || ""}</h1>
|
||||
{/snippet}
|
||||
{#snippet action()}
|
||||
<MenuSpaceButton {url} />
|
||||
{/snippet}
|
||||
</PageBar>
|
||||
|
||||
<PageContent class="flex flex-col gap-3 p-2 pt-4">
|
||||
{#if $event}
|
||||
{#if !showReply}
|
||||
<div class="flex justify-end px-2 pb-2">
|
||||
<Button class="btn btn-primary" onclick={openReply}>
|
||||
<Icon icon="reply" />
|
||||
Leave comment
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
{#each sortBy(e => -e.created_at, $replies).slice(0, showAll ? undefined : 4) as reply (reply.id)}
|
||||
<NoteCard event={reply} class="card2 bg-alt z-feature w-full">
|
||||
<div class="col-3 ml-12">
|
||||
<Content showEntire event={reply} />
|
||||
<CalendarEventActions event={reply} {url} />
|
||||
</div>
|
||||
</NoteCard>
|
||||
{/each}
|
||||
{#if !showAll && $replies.length > 4}
|
||||
<div class="flex justify-center">
|
||||
<Button class="btn btn-link" onclick={expand}>
|
||||
<Icon icon="sort-vertical" />
|
||||
Show all {$replies.length} replies
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="card2 bg-alt col-3 z-feature">
|
||||
<div class="flex items-start gap-4">
|
||||
<CalendarEventDate event={$event} />
|
||||
|
|
@ -96,6 +89,32 @@
|
|||
<CalendarEventActions {url} event={$event} />
|
||||
</div>
|
||||
</div>
|
||||
{#if !showAll && $replies.length > 4}
|
||||
<div class="flex justify-center">
|
||||
<Button class="btn btn-link" onclick={expand}>
|
||||
<Icon icon="sort-vertical" />
|
||||
Show all {$replies.length} replies
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
{#each sortBy(e => e.created_at, $replies).slice(0, showAll ? undefined : 4) as reply (reply.id)}
|
||||
<NoteCard event={reply} class="card2 bg-alt z-feature w-full">
|
||||
<div class="col-3 ml-12">
|
||||
<Content showEntire event={reply} />
|
||||
<CalendarEventActions event={reply} {url} />
|
||||
</div>
|
||||
</NoteCard>
|
||||
{/each}
|
||||
{#if showReply}
|
||||
<EventReply {url} event={$event} onClose={closeReply} onSubmit={closeReply} />
|
||||
{:else}
|
||||
<div class="flex justify-end px-2 pb-2">
|
||||
<Button class="btn btn-primary" onclick={openReply}>
|
||||
<Icon icon="reply" />
|
||||
Leave comment
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
{#await sleep(5000)}
|
||||
<Spinner loading>Loading comments...</Spinner>
|
||||
|
|
@ -103,23 +122,4 @@
|
|||
<p>Failed to load comments.</p>
|
||||
{/await}
|
||||
{/if}
|
||||
<PageBar class="!mx-0">
|
||||
{#snippet icon()}
|
||||
<div>
|
||||
<Button class="btn btn-neutral btn-sm flex-nowrap whitespace-nowrap" onclick={back}>
|
||||
<Icon icon="alt-arrow-left" />
|
||||
<span class="hidden sm:inline">Go back</span>
|
||||
</Button>
|
||||
</div>
|
||||
{/snippet}
|
||||
{#snippet title()}
|
||||
<h1 class="text-xl">{getTagValue("title", $event?.tags || []) || ""}</h1>
|
||||
{/snippet}
|
||||
{#snippet action()}
|
||||
<MenuSpaceButton {url} />
|
||||
{/snippet}
|
||||
</PageBar>
|
||||
</div>
|
||||
{#if showReply}
|
||||
<EventReply {url} event={$event} onClose={closeReply} onSubmit={closeReply} />
|
||||
{/if}
|
||||
</PageContent>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import PageBar from "@lib/components/PageBar.svelte"
|
||||
import PageContent from "@lib/components/PageContent.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import MenuSpaceButton from "@app/components/MenuSpaceButton.svelte"
|
||||
import ThreadItem from "@app/components/ThreadItem.svelte"
|
||||
|
|
@ -73,7 +74,6 @@
|
|||
})
|
||||
</script>
|
||||
|
||||
<div class="relative flex h-screen flex-col" bind:this={element}>
|
||||
<PageBar>
|
||||
{#snippet icon()}
|
||||
<div class="center">
|
||||
|
|
@ -93,7 +93,8 @@
|
|||
</div>
|
||||
{/snippet}
|
||||
</PageBar>
|
||||
<div class="flex flex-grow flex-col gap-2 overflow-auto p-2">
|
||||
|
||||
<PageContent bind:element class="flex flex-col gap-2 p-2 pt-4">
|
||||
{#each events as event (event.id)}
|
||||
<div in:fly>
|
||||
<ThreadItem {url} event={$state.snapshot(event)} />
|
||||
|
|
@ -110,5 +111,4 @@
|
|||
{/if}
|
||||
</Spinner>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</PageContent>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
import {deriveEvents} from "@welshman/store"
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import PageBar from "@lib/components/PageBar.svelte"
|
||||
import PageContent from "@lib/components/PageContent.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import Content from "@app/components/Content.svelte"
|
||||
|
|
@ -50,47 +51,7 @@
|
|||
})
|
||||
</script>
|
||||
|
||||
<div class="relative flex flex-col-reverse gap-3 px-2">
|
||||
<div class="absolute left-[51px] top-32 h-[calc(100%-248px)] w-[2px] bg-neutral"></div>
|
||||
{#if $event}
|
||||
{#if !showReply}
|
||||
<div class="flex justify-end px-2 pb-2">
|
||||
<Button class="btn btn-primary" onclick={openReply}>
|
||||
<Icon icon="reply" />
|
||||
Reply to thread
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
{#each sortBy(e => -e.created_at, $replies).slice(0, showAll ? undefined : 4) as reply (reply.id)}
|
||||
<NoteCard event={reply} class="card2 bg-alt z-feature w-full">
|
||||
<div class="col-3 ml-12">
|
||||
<Content showEntire event={reply} />
|
||||
<ThreadActions event={reply} {url} />
|
||||
</div>
|
||||
</NoteCard>
|
||||
{/each}
|
||||
{#if !showAll && $replies.length > 4}
|
||||
<div class="flex justify-center">
|
||||
<Button class="btn btn-link" onclick={expand}>
|
||||
<Icon icon="sort-vertical" />
|
||||
Show all {$replies.length} replies
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
<NoteCard event={$event} class="card2 bg-alt z-feature w-full">
|
||||
<div class="col-3 ml-12">
|
||||
<Content showEntire event={$event} relays={[url]} />
|
||||
<ThreadActions event={$event} {url} />
|
||||
</div>
|
||||
</NoteCard>
|
||||
{:else}
|
||||
{#await sleep(5000)}
|
||||
<Spinner loading>Loading thread...</Spinner>
|
||||
{:then}
|
||||
<p>Failed to load thread.</p>
|
||||
{/await}
|
||||
{/if}
|
||||
<PageBar class="!mx-0">
|
||||
<PageBar>
|
||||
{#snippet icon()}
|
||||
<div>
|
||||
<Button class="btn btn-neutral btn-sm flex-nowrap whitespace-nowrap" onclick={back}>
|
||||
|
|
@ -108,7 +69,48 @@
|
|||
</div>
|
||||
{/snippet}
|
||||
</PageBar>
|
||||
|
||||
<PageContent class="flex flex-col p-2 pt-4">
|
||||
{#if $event}
|
||||
<div class="flex flex-col gap-3">
|
||||
<NoteCard event={$event} class="card2 bg-alt z-feature w-full">
|
||||
<div class="col-3 ml-12">
|
||||
<Content showEntire event={$event} relays={[url]} />
|
||||
<ThreadActions event={$event} {url} />
|
||||
</div>
|
||||
</NoteCard>
|
||||
{#if !showAll && $replies.length > 4}
|
||||
<div class="flex justify-center">
|
||||
<Button class="btn btn-link" onclick={expand}>
|
||||
<Icon icon="sort-vertical" />
|
||||
Show all {$replies.length} replies
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
{#each sortBy(e => -e.created_at, $replies).slice(0, showAll ? undefined : 4) as reply (reply.id)}
|
||||
<NoteCard event={reply} class="card2 bg-alt z-feature w-full">
|
||||
<div class="col-3 ml-12">
|
||||
<Content showEntire event={reply} />
|
||||
<ThreadActions event={reply} {url} />
|
||||
</div>
|
||||
</NoteCard>
|
||||
{/each}
|
||||
</div>
|
||||
{#if showReply}
|
||||
<EventReply {url} event={$event} onClose={closeReply} onSubmit={closeReply} />
|
||||
{:else}
|
||||
<div class="flex justify-end p-2">
|
||||
<Button class="btn btn-primary" onclick={openReply}>
|
||||
<Icon icon="reply" />
|
||||
Reply to thread
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
{#await sleep(5000)}
|
||||
<Spinner loading>Loading thread...</Spinner>
|
||||
{:then}
|
||||
<p>Failed to load thread.</p>
|
||||
{/await}
|
||||
{/if}
|
||||
</PageContent>
|
||||
|
|
|
|||
Loading…
Reference in a new issue