···
if ($accounts.length > 0) {
32
+
loaderState.status = 'LOADING';
selectedDid = $accounts[0].did;
Promise.all($accounts.map(loginAccount)).then(() => {
34
-
loaderState.isFirstLoad = true;
···
let posts = new SvelteMap<Did, SvelteMap<ResourceUri, AppBskyFeedPost.Main>>();
69
-
let cursors = new SvelteMap<Did, string | undefined>();
69
+
let cursors = new SvelteMap<Did, { value?: string; end: boolean }>();
const fetchTimeline = async (account: Account) => {
const client = clients.get(account.did);
const cursor = cursors.get(account.did);
76
-
const accPosts = await fetchPostsWithBacklinks(client, account.did, cursor, 6);
76
+
if (cursor && cursor.end) return;
78
+
const accPosts = await fetchPostsWithBacklinks(client, account.did, cursor?.value, 6);
throw `failed to fetch posts for account ${account.handle}: ${accPosts.error}`;
81
-
// Update cursor for next fetch
82
-
cursors.set(account.did, accPosts.value.cursor);
83
+
// if the cursor is undefined, we've reached the end of the timeline
84
+
if (!accPosts.value.cursor) {
85
+
cursors.set(account.did, { ...cursor, end: true });
89
+
cursors.set(account.did, { value: accPosts.value.cursor, end: false });
const accTimeline = await hydratePosts(client, accPosts.value.posts);
if (!posts.has(account.did)) {
posts.set(account.did, new SvelteMap(accTimeline));
···
115
+
if (cursors.values().every((cursor) => cursor.end)) loaderState.complete();
···
179
-
if (!childrenMap.has(post.parentUri)) {
180
-
childrenMap.set(post.parentUri, []);
186
+
if (!childrenMap.has(post.parentUri)) childrenMap.set(post.parentUri, []);
childrenMap.get(post.parentUri)!.push(post);
// Sort children by time (newest first)
186
-
for (const children of childrenMap.values()) {
187
-
children.sort((a, b) => b.newestTime - a.newestTime);
193
+
.forEach((children) => children.sort((a, b) => b.newestTime - a.newestTime));
// Helper to create a thread from posts
···
const addWithChildren = (post: ThreadPost) => {
const children = childrenMap.get(post.uri) || [];
210
-
for (const child of children) {
211
-
addWithChildren(child);
215
+
children.forEach(addWithChildren);
addWithChildren(startPost);
···
<div class="mt-4 overflow-y-scroll [scrollbar-width:none]" bind:this={scrollContainer}>
339
-
triggerLoad={loadMore}
340
-
intersectionOptions={{ root: scrollContainer }}
342
-
{@render threadsView()}
343
-
{#snippet loading()}
344
-
<div class="flex justify-center py-4">
346
-
class="h-8 w-8 animate-spin rounded-full border-4 border-t-transparent"
347
-
style="border-color: {theme.accent} {theme.accent} {theme.accent} transparent;"
352
-
<div class="flex justify-center py-4">
353
-
<p class="text-sm opacity-80" style="color: {theme.fg};">
354
-
an error occurred while loading posts: {loadError}
340
+
{#if $accounts.length > 0}
341
+
{@render renderThreads()}
343
+
<div class="flex justify-center py-4">
344
+
<p class="text-xl opacity-80" style="color: {theme.fg};">
345
+
<span class="text-4xl">x_x</span> <br /> no accounts are logged in!
352
+
{#snippet renderThreads()}
355
+
triggerLoad={loadMore}
356
+
loopDetectionTimeout={0}
357
+
intersectionOptions={{ root: scrollContainer }}
359
+
{@render threadsView()}
360
+
{#snippet noData()}
361
+
<div class="flex justify-center py-4">
362
+
<p class="text-xl opacity-80" style="color: {theme.fg};">
363
+
all posts seen! <span class="text-2xl">:o</span>
367
+
{#snippet loading()}
368
+
<div class="flex justify-center">
370
+
class="h-12 w-12 animate-spin rounded-full border-4 border-t-transparent"
371
+
style="border-color: {theme.accent} {theme.accent} {theme.accent} transparent;"
376
+
<div class="flex justify-center py-4">
377
+
<p class="text-xl opacity-80" style="color: {theme.fg};">
378
+
<span class="text-4xl">:(</span> <br /> an error occurred while loading posts: {loadError}
{#each threads as thread (thread.rootUri)}
<div class="flex {reverseChronological ? 'flex-col' : 'flex-col-reverse'} mb-6.5">
{#if thread.branchParentPost}
{@const post = thread.branchParentPost}
<div class="mb-1.5 flex items-center gap-1.5">
368
-
<span class="text-sm opacity-60" style="color: {theme.fg};"
391
+
<span class="text-sm text-nowrap opacity-60" style="color: {theme.fg};"
>{reverseChronological ? '↱' : '↳'}</span