Thread viewer for Bluesky
at master 73 lines 1.7 kB view raw
1<script lang="ts"> 2 import { api } from '../api.js'; 3 import { Post } from '../models/posts.js'; 4 import * as paginator from '../utils/paginator.js'; 5 import MainLoader from '../components/MainLoader.svelte'; 6 import PostComponent from '../components/posts/PostComponent.svelte'; 7 8 let { hashtag }: { hashtag: string } = $props(); 9 hashtag = hashtag.replace(/^\#/, ''); 10 11 let posts: Post[] = $state([]); 12 let firstPageLoaded = $state(false); 13 let loadingFailed = $state(false); 14 15 let isLoading = false; 16 let finished = false; 17 let cursor: string | undefined; 18 19 paginator.loadInPages(async () => { 20 if (isLoading || finished) { return } 21 isLoading = true; 22 23 try { 24 let data = await api.getHashtagFeed(hashtag, cursor); 25 let batch = data.posts.map((j: json) => new Post(j)) as Post[]; 26 firstPageLoaded = true; 27 28 posts.push(...batch); 29 30 isLoading = false; 31 cursor = data.cursor; 32 33 if (!cursor || posts.length == 0) { 34 finished = true; 35 } 36 } catch(error) { 37 console.log(error); 38 isLoading = false; 39 loadingFailed = true; 40 } 41 }); 42</script> 43 44<svelte:head> 45 <title>#{hashtag} - Skythread</title> 46</svelte:head> 47 48{#if firstPageLoaded} 49 <main class="hashtag"> 50 <header> 51 <h2> 52 {#if posts.length > 0} 53 Posts tagged: #{hashtag} 54 {:else} 55 No posts tagged #{hashtag}. 56 {/if} 57 </h2> 58 </header> 59 60 {#each posts as post (post.uri)} 61 <PostComponent {post} placement="feed" /> 62 {/each} 63 </main> 64{:else if !loadingFailed} 65 <MainLoader /> 66{/if} 67 68<style> 69 .hashtag > :global(.post) { 70 padding-bottom: 10px; 71 border-bottom: 1px solid #ddd; 72 } 73</style>