mirror of
https://git.shipoclu.com/moon/plspace.git
synced 2026-08-13 02:42:30 +00:00
initial commit
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* A timeline, presented as a blog: "My Blog" (home), "This Server" (local),
|
||||
* "The Whole Network" (federated), or a hashtag.
|
||||
*/
|
||||
import { untrack } from 'svelte'
|
||||
import type { Status } from '$lib/api/types'
|
||||
import type { TimelineKind } from '$lib/api/endpoints'
|
||||
import { session } from '$lib/stores/session.svelte'
|
||||
import { Feed } from '$lib/stores/feed.svelte'
|
||||
import { fetchTimeline, instanceDomain } from '$lib/api/endpoints'
|
||||
import Module from '$components/common/Module.svelte'
|
||||
import TabBar from '$components/common/TabBar.svelte'
|
||||
import BlogList from '$components/blog/BlogList.svelte'
|
||||
import Composer from '$components/blog/Composer.svelte'
|
||||
|
||||
interface Props {
|
||||
kind: TimelineKind
|
||||
tag?: string
|
||||
}
|
||||
|
||||
let { kind, tag }: Props = $props()
|
||||
|
||||
let feed = $state<Feed<Status>>(new Feed<Status>(async () => ({ items: [], links: {} })))
|
||||
|
||||
const domain = $derived(session.host ? instanceDomain(session.instance, session.host) : '')
|
||||
|
||||
const title = $derived(
|
||||
kind === 'home'
|
||||
? 'My Blog'
|
||||
: kind === 'local'
|
||||
? `Blogs on ${domain}`
|
||||
: kind === 'tag'
|
||||
? `#${tag}`
|
||||
: 'The Whole Network',
|
||||
)
|
||||
|
||||
const tabs = $derived([
|
||||
...(session.signedIn ? [{ label: 'My Blog', href: '#/timeline/home' }] : []),
|
||||
{ label: 'This Server', href: '#/timeline/local' },
|
||||
{ label: 'Whole Network', href: '#/timeline/public' },
|
||||
])
|
||||
|
||||
const currentTab = $derived(kind === 'tag' ? '' : `#/timeline/${kind}`)
|
||||
|
||||
$effect(() => {
|
||||
const currentKind = kind
|
||||
const currentTag = tag
|
||||
const host = session.host
|
||||
const authed = session.signedIn
|
||||
if (!host) return
|
||||
|
||||
untrack(() => {
|
||||
// Home needs a token; fall back rather than showing a 401.
|
||||
const resolved: TimelineKind = currentKind === 'home' && !authed ? 'local' : currentKind
|
||||
feed = new Feed<Status>((cursor) =>
|
||||
fetchTimeline(session.api, resolved, cursor, { tag: currentTag }),
|
||||
)
|
||||
void feed.reload()
|
||||
document.title = `${title} | plspace`
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="page timeline-page" data-timeline={kind} data-tag={tag ?? ''}>
|
||||
<h1 class="page-title">{title}</h1>
|
||||
|
||||
{#if kind !== 'tag'}
|
||||
<TabBar {tabs} current={currentTab} label="Timelines" />
|
||||
{/if}
|
||||
|
||||
{#if kind === 'home' && !session.signedIn}
|
||||
<p class="notice">
|
||||
You're browsing as a guest, so this is <strong>{domain}</strong>'s local timeline.
|
||||
<a href="#/login">Sign in</a> to read your own.
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<div class="layout--single">
|
||||
{#if kind === 'home' && session.signedIn}
|
||||
<Module title="Post a new entry">
|
||||
<Composer onposted={(status) => feed.prepend(status)} />
|
||||
</Module>
|
||||
{/if}
|
||||
|
||||
<Module title={title} variant="band">
|
||||
<BlogList
|
||||
{feed}
|
||||
emptyText={kind === 'tag'
|
||||
? `Nobody has posted with #${tag} that this server knows about.`
|
||||
: 'There are no Blog Entries yet.'}
|
||||
longFormDate
|
||||
/>
|
||||
</Module>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user