Implement issues for v1.1.0 #20
11
src/lib/components/LoadMoreComponent.svelte
Normal file
11
src/lib/components/LoadMoreComponent.svelte
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<script>
|
||||||
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
function loadOlderPosts() {
|
||||||
|
dispatch('loadOlderPosts');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button on:click={loadOlderPosts}>Load More</button>
|
@ -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<Post[]>((resolve, reject) => {
|
let promise = await new Promise<Post[]>((resolve, reject) => {
|
||||||
let filter_query;
|
let filter_query;
|
||||||
let params: any = { $limit: limit };
|
let params: any = { $limit: limit };
|
||||||
if (since === null) {
|
if (since === null && before === null) {
|
||||||
filter_query = '';
|
filter_query = '';
|
||||||
} else {
|
} else if (since !== null) {
|
||||||
filter_query = 'WHERE posts.created_at > $since';
|
filter_query = 'WHERE posts.created_at > $since';
|
||||||
params.$since = 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,
|
const sql = `SELECT posts.id, posts.content, posts.created_at, posts.url,
|
||||||
accounts.id AS account_id, accounts.acct, accounts.username, accounts.display_name,
|
accounts.id AS account_id, accounts.acct, accounts.username, accounts.display_name,
|
||||||
|
@ -4,6 +4,7 @@ import type { PageData } from './$types';
|
|||||||
import type { Post } from '$lib/mastodon/response';
|
import type { Post } from '$lib/mastodon/response';
|
||||||
import { PUBLIC_REFRESH_INTERVAL } from '$env/static/public';
|
import { PUBLIC_REFRESH_INTERVAL } from '$env/static/public';
|
||||||
import PostComponent from '$lib/components/PostComponent.svelte';
|
import PostComponent from '$lib/components/PostComponent.svelte';
|
||||||
|
import LoadMoreComponent from '$lib/components/LoadMoreComponent.svelte';
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
|
|
||||||
@ -19,8 +20,13 @@ onMount(async () => {
|
|||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then((resp: Post[]) => {
|
.then((resp: Post[]) => {
|
||||||
if (resp.length > 0) {
|
if (resp.length > 0) {
|
||||||
data.posts = resp.concat(data.posts);
|
// Prepend new posts, filter dupes
|
||||||
console.log('updated data', resp, data.posts);
|
// 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 => {
|
.catch(e => {
|
||||||
@ -33,7 +39,33 @@ onMount(async () => {
|
|||||||
clearInterval(interval)
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>Metalhead.club music list</title>
|
<title>Metalhead.club music list</title>
|
||||||
@ -45,9 +77,10 @@ onMount(async () => {
|
|||||||
{#if data.posts.length === 0}
|
{#if data.posts.length === 0}
|
||||||
Sorry, no posts recommending music aave been found yet
|
Sorry, no posts recommending music aave been found yet
|
||||||
{/if}
|
{/if}
|
||||||
{#each data.posts as post (post.id)}
|
{#each data.posts as post (post.url)}
|
||||||
<div class="post"><PostComponent {post} /></div>
|
<div class="post"><PostComponent {post} /></div>
|
||||||
{/each}
|
{/each}
|
||||||
|
<LoadMoreComponent on:loadOlderPosts={loadOlderPosts}/>
|
||||||
</div>
|
</div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,11 +5,12 @@ import type { RequestHandler } from './$types';
|
|||||||
|
|
||||||
export const GET = (async ({ url }) => {
|
export const GET = (async ({ url }) => {
|
||||||
const since = url.searchParams.get('since');
|
const since = url.searchParams.get('since');
|
||||||
|
const before = url.searchParams.get('before');
|
||||||
let count = Number.parseInt(url.searchParams.get('count') || '');
|
let count = Number.parseInt(url.searchParams.get('count') || '');
|
||||||
if (isNaN(count)) {
|
if (isNaN(count)) {
|
||||||
count = 20;
|
count = 20;
|
||||||
}
|
}
|
||||||
count = Math.min(count, 100);
|
count = Math.min(count, 100);
|
||||||
const posts = await getPosts(since, count);
|
const posts = await getPosts(since, before, count);
|
||||||
return json(posts);
|
return json(posts);
|
||||||
}) satisfies RequestHandler;
|
}) satisfies RequestHandler;
|
Loading…
Reference in New Issue
Block a user