From e8e864bdfc57b49eb552428ba5ed6e926af6d911 Mon Sep 17 00:00:00 2001 From: Max Nuding Date: Mon, 3 Apr 2023 17:24:59 +0200 Subject: [PATCH] Add basic loading of older posts --- src/lib/components/LoadMoreComponent.svelte | 11 ++++++ src/lib/server/db.ts | 10 +++-- src/routes/+page.svelte | 41 +++++++++++++++++++-- src/routes/api/posts/+server.ts | 17 +++++---- 4 files changed, 64 insertions(+), 15 deletions(-) create mode 100644 src/lib/components/LoadMoreComponent.svelte diff --git a/src/lib/components/LoadMoreComponent.svelte b/src/lib/components/LoadMoreComponent.svelte new file mode 100644 index 0000000..881c013 --- /dev/null +++ b/src/lib/components/LoadMoreComponent.svelte @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/src/lib/server/db.ts b/src/lib/server/db.ts index 7f8ba92..042b983 100644 --- a/src/lib/server/db.ts +++ b/src/lib/server/db.ts @@ -172,15 +172,19 @@ export function savePost(post: Post): void { }); } -export async function getPosts(since: string | null, limit: number) { +export async function getPosts(since: string | null, before: string | null, limit: number) { let promise = await new Promise((resolve, reject) => { let filter_query; let params: any = { $limit: limit }; - if (since === null) { + if (since === null && before === null) { filter_query = ''; - } else { + } else if (since !== null) { filter_query = 'WHERE posts.created_at > $since'; params.$since = since; + } else if (before !== null) { + // Setting both, before and since doesn't make sense, so this case is not explicitly handled + filter_query = 'WHERE posts.created_at < $before'; + params.$before = before; } const sql = `SELECT posts.id, posts.content, posts.created_at, posts.url, accounts.id AS account_id, accounts.acct, accounts.username, accounts.display_name, diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 03da0ec..ac27b3e 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -4,6 +4,7 @@ import type { PageData } from './$types'; import type { Post } from '$lib/mastodon/response'; import { PUBLIC_REFRESH_INTERVAL } from '$env/static/public'; import PostComponent from '$lib/components/PostComponent.svelte'; +import LoadMoreComponent from '$lib/components/LoadMoreComponent.svelte'; export let data: PageData; @@ -19,8 +20,13 @@ onMount(async () => { .then(r => r.json()) .then((resp: Post[]) => { if (resp.length > 0) { - data.posts = resp.concat(data.posts); - console.log('updated data', resp, data.posts); + // Prepend new posts, filter dupes + // There shouldn't be any duplicates, but better be safe than sorry + const combined = resp.concat(data.posts); + const filteredPosts = combined.filter((obj, index, arr) => { + return arr.map(mapObj => mapObj.url).indexOf(obj.url) === index; + }); + data.posts = filteredPosts; } }) .catch(e => { @@ -33,7 +39,33 @@ onMount(async () => { clearInterval(interval) } } -}) +}); + +async function loadOlderPosts() { + const params = new URLSearchParams(); + if (data.posts.length > 0) { + params.set('before', data.posts[data.posts.length - 1].created_at); + } + await fetch(`/api/posts?${params}`) + .then(r => r.json()) + .then((resp: Post[]) => { + if (resp.length > 0) { + // Append old posts, filter dupes + // There shouldn't be any duplicates, but better be safe than sorry + const combined = data.posts.concat(resp); + const filteredPosts = combined.filter((obj, index, arr) => { + return arr.map(mapObj => mapObj.url).indexOf(obj.url) === index; + }); + data.posts = filteredPosts; + } + }) + .catch(e => { + // TODO: Show error in UI + console.error('Error loading older posts', e); + }); + +} + Metalhead.club music list @@ -45,9 +77,10 @@ onMount(async () => { {#if data.posts.length === 0} Sorry, no posts recommending music aave been found yet {/if} - {#each data.posts as post (post.id)} + {#each data.posts as post (post.url)}
{/each} +
diff --git a/src/routes/api/posts/+server.ts b/src/routes/api/posts/+server.ts index 24c4fcd..4b67da2 100644 --- a/src/routes/api/posts/+server.ts +++ b/src/routes/api/posts/+server.ts @@ -4,12 +4,13 @@ import { json } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; export const GET = (async ({ url }) => { - const since = url.searchParams.get('since'); - let count = Number.parseInt(url.searchParams.get('count') || ''); - if (isNaN(count)) { - count = 20; - } - count = Math.min(count, 100); - const posts = await getPosts(since, count); - return json(posts); + const since = url.searchParams.get('since'); + const before = url.searchParams.get('before'); + let count = Number.parseInt(url.searchParams.get('count') || ''); + if (isNaN(count)) { + count = 20; + } + count = Math.min(count, 100); + const posts = await getPosts(since, before, count); + return json(posts); }) satisfies RequestHandler; \ No newline at end of file