Thread viewer for Bluesky
1<script lang="ts">
2 import { accountAPI } from '../api.js';
3 import { Post } from '../models/posts.js';
4 import * as paginator from '../utils/paginator.js';
5 import FeedPostParent from '../components/posts/FeedPostParent.svelte';
6 import MainLoader from '../components/MainLoader.svelte';
7 import PostComponent from '../components/posts/PostComponent.svelte';
8
9 let posts: Post[] = $state([]);
10 let firstPageLoaded = $state(false);
11 let loadingFailed = $state(false);
12
13 let isLoading = false;
14 let finished = false;
15 let cursor: string | undefined;
16
17 paginator.loadInPages(async (next) => {
18 if (isLoading || finished) { return }
19 isLoading = true;
20
21 try {
22 let data = await accountAPI.loadMentions(cursor);
23 let batch = data.posts.map(x => new Post(x));
24
25 if (!firstPageLoaded && batch.length > 0) {
26 firstPageLoaded = true;
27 }
28
29 posts.push(...batch);
30
31 isLoading = false;
32 cursor = data.cursor;
33
34 if (!cursor) {
35 finished = true;
36 } else if (batch.length == 0) {
37 next();
38 }
39 } catch(error) {
40 console.log(error);
41 isLoading = false;
42 loadingFailed = true;
43 }
44 });
45</script>
46
47<svelte:head>
48 <title>Notifications - Skythread</title>
49</svelte:head>
50
51{#if firstPageLoaded}
52 <main class="notifications">
53 <header>
54 <h2>Replies & Mentions:</h2>
55 </header>
56
57 {#each posts as post (post.uri)}
58 <!-- note: posts here are loaded via getPosts, so they don't include full parent/thread info -->
59 {#if post.parentReference}
60 <FeedPostParent uri={post.parentReference.uri} />
61 {/if}
62
63 <PostComponent {post} placement="feed" />
64 {/each}
65 </main>
66{:else if !loadingFailed}
67 <MainLoader />
68{/if}
69
70<style>
71 .notifications :global {
72 .post {
73 padding-bottom: 4px;
74 border-bottom: 1px solid #ddd;
75 margin-top: 24px;
76 }
77
78 .back {
79 margin-left: 22px;
80 margin-bottom: -12px;
81 margin-top: 15px;
82 }
83
84 .back, .back a {
85 font-size: 10pt;
86 }
87
88 .back i {
89 font-size: 9pt;
90 margin-right: 2px;
91 }
92 }
93</style>