mirror of
https://git.shipoclu.com/moon/plspace.git
synced 2026-08-14 03:02:31 +00:00
quote posts
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user