mirror of
https://git.shipoclu.com/moon/plspace.git
synced 2026-08-14 03:02:31 +00:00
91 lines
2.7 KiB
Svelte
91 lines
2.7 KiB
Svelte
<script lang="ts">
|
|
/** Paginated posts that quote one source entry. */
|
|
import { untrack } from 'svelte'
|
|
import type { Status } from '$lib/api/types'
|
|
import { useAppServices } from '$lib/app-services'
|
|
import { Feed } from '$lib/stores/feed.svelte'
|
|
import { useTimelineRefresh } from '$lib/timeline-refresh'
|
|
import Module from '$components/common/Module.svelte'
|
|
import BlogEntry from '$components/blog/BlogEntry.svelte'
|
|
import BlogList from '$components/blog/BlogList.svelte'
|
|
|
|
interface Props {
|
|
id: string
|
|
}
|
|
|
|
let { id }: Props = $props()
|
|
const { endpoints, session } = useAppServices()
|
|
const timelineRefresh = useTimelineRefresh()
|
|
|
|
let source = $state<Status | null>(null)
|
|
let sourceError = $state<string | null>(null)
|
|
let sourceLoading = $state(true)
|
|
let loadGeneration = 0
|
|
let feed = $state<Feed<Status>>(
|
|
new Feed<Status>(async () => ({ items: [], links: {} })),
|
|
)
|
|
|
|
$effect(() => {
|
|
const currentId = id
|
|
const generation = ++loadGeneration
|
|
source = null
|
|
sourceError = null
|
|
sourceLoading = true
|
|
feed = new Feed<Status>((cursor) => endpoints.fetchQuotes(session.api, currentId, cursor))
|
|
untrack(() => {
|
|
void feed.reload()
|
|
void loadSource(currentId, generation)
|
|
})
|
|
return () => {
|
|
if (generation === loadGeneration) loadGeneration += 1
|
|
}
|
|
})
|
|
|
|
$effect(() => timelineRefresh?.register(() => void feed.refresh()))
|
|
|
|
async function loadSource(currentId: string, generation: number): Promise<void> {
|
|
try {
|
|
const found = await endpoints.fetchStatus(session.api, currentId)
|
|
if (generation === loadGeneration && id === currentId) {
|
|
source = found
|
|
document.title = 'Quotes | plspace'
|
|
}
|
|
} catch (cause) {
|
|
if (generation === loadGeneration) {
|
|
sourceError = cause instanceof Error ? cause.message : 'Could not load the original entry.'
|
|
}
|
|
} finally {
|
|
if (generation === loadGeneration) sourceLoading = false
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<div class="page quotes-page">
|
|
<h1 class="page-title">Quotes of this Blog Entry</h1>
|
|
|
|
<div class="layout--single">
|
|
<Module title="Original Entry" variant="band">
|
|
{#if sourceLoading}
|
|
<p class="loading-note">Loading original entry…</p>
|
|
{:else if sourceError}
|
|
<p class="error-note" role="alert">{sourceError}</p>
|
|
{:else if source}
|
|
<BlogEntry
|
|
status={source}
|
|
compact
|
|
onupdate={(updated) => (source = updated)}
|
|
/>
|
|
{/if}
|
|
</Module>
|
|
|
|
<Module title="Entries quoting this" variant="band">
|
|
<BlogList
|
|
{feed}
|
|
emptyText="Nobody has quoted this entry yet."
|
|
label="View More Quotes"
|
|
longFormDate
|
|
/>
|
|
</Module>
|
|
</div>
|
|
</div>
|