You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
2.7 KiB
112 lines
2.7 KiB
<script lang="ts"> |
|
import Kind1Post from './Kind1Post.svelte'; |
|
import CreateKind1Form from './CreateKind1Form.svelte'; |
|
import { nostrClient } from '../../services/nostr/nostr-client.js'; |
|
import { onMount } from 'svelte'; |
|
import type { NostrEvent } from '../../types/nostr.js'; |
|
|
|
let posts = $state<NostrEvent[]>([]); |
|
let loading = $state(true); |
|
let replyingTo = $state<NostrEvent | null>(null); |
|
let showNewPostForm = $state(false); |
|
|
|
onMount(async () => { |
|
await nostrClient.initialize(); |
|
loadFeed(); |
|
}); |
|
|
|
async function loadFeed() { |
|
loading = true; |
|
try { |
|
const config = nostrClient.getConfig(); |
|
|
|
const filters = [ |
|
{ |
|
kinds: [1], |
|
limit: 50 |
|
} |
|
]; |
|
|
|
const events = await nostrClient.fetchEvents( |
|
filters, |
|
[...config.defaultRelays], |
|
{ useCache: true, cacheResults: true, onUpdate: (updated) => { |
|
posts = sortPosts(updated); |
|
}} |
|
); |
|
|
|
posts = sortPosts(events); |
|
} catch (error) { |
|
console.error('Error loading feed:', error); |
|
} finally { |
|
loading = false; |
|
} |
|
} |
|
|
|
function sortPosts(events: NostrEvent[]): NostrEvent[] { |
|
// Sort by created_at descending (newest first) |
|
return [...events].sort((a, b) => b.created_at - a.created_at); |
|
} |
|
|
|
function handleReply(post: NostrEvent) { |
|
replyingTo = post; |
|
showNewPostForm = true; |
|
} |
|
|
|
function handlePostPublished() { |
|
replyingTo = null; |
|
showNewPostForm = false; |
|
loadFeed(); |
|
} |
|
</script> |
|
|
|
<div class="kind1-feed"> |
|
<div class="feed-header mb-4"> |
|
<h1 class="text-2xl font-bold mb-4">Feed</h1> |
|
<button |
|
onclick={() => (showNewPostForm = !showNewPostForm)} |
|
class="px-4 py-2 bg-fog-accent dark:bg-fog-dark-accent text-white rounded hover:opacity-90" |
|
> |
|
{showNewPostForm ? 'Cancel' : 'New Post'} |
|
</button> |
|
</div> |
|
|
|
{#if showNewPostForm} |
|
<div class="new-post-form mb-4"> |
|
<CreateKind1Form |
|
parentEvent={replyingTo} |
|
onPublished={handlePostPublished} |
|
onCancel={() => { |
|
showNewPostForm = false; |
|
replyingTo = null; |
|
}} |
|
/> |
|
</div> |
|
{/if} |
|
|
|
{#if loading} |
|
<p class="text-fog-text-light dark:text-fog-dark-text-light">Loading feed...</p> |
|
{:else if posts.length === 0} |
|
<p class="text-fog-text-light dark:text-fog-dark-text-light">No posts yet. Be the first to post!</p> |
|
{:else} |
|
<div class="posts-list"> |
|
{#each posts as post (post.id)} |
|
<Kind1Post {post} onReply={handleReply} /> |
|
{/each} |
|
</div> |
|
{/if} |
|
</div> |
|
|
|
<style> |
|
.kind1-feed { |
|
max-width: var(--content-width); |
|
margin: 0 auto; |
|
padding: 1rem; |
|
} |
|
|
|
.feed-header { |
|
display: flex; |
|
justify-content: space-between; |
|
align-items: center; |
|
} |
|
</style>
|
|
|