Fix #4: Implement "Load More" button

This commit is contained in:
Max Nuding 2023-04-04 08:45:20 +02:00
parent 02a352a122
commit 8ed804a922
Signed by: phlaym
GPG Key ID: A06651BAB6777237
2 changed files with 49 additions and 8 deletions

View File

@ -1,6 +1,16 @@
<script> <script lang="ts">
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
export let moreAvailable: boolean = false;
export let isLoading: boolean = false;
let displayText = '';
let title = '';
let disabled: boolean;
$: displayText = isLoading ? 'Loading...' : 'Load More';
$: disabled = !moreAvailable || isLoading;
$: title = moreAvailable ? 'Load More' : 'No more posts available';
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
function loadOlderPosts() { function loadOlderPosts() {
@ -8,4 +18,23 @@
} }
</script> </script>
<button on:click={loadOlderPosts}>Load More</button> <button on:click={loadOlderPosts} {disabled} {title}>{displayText}</button>
<style>
button {
padding: 0.75em;
border-radius: 3px;
border: none;
background-color: var(--color-link);
color: white;
cursor: grab;
transition: all 0.2s ease-in-out;
}
button:hover:not(:disabled) {
background-color: var(--color-link-visited);
}
button:disabled {
cursor: not-allowed;
background-color: grey;
}
</style>

View File

@ -9,6 +9,8 @@ import LoadMoreComponent from '$lib/components/LoadMoreComponent.svelte';
export let data: PageData; export let data: PageData;
let interval: NodeJS.Timer | null = null; let interval: NodeJS.Timer | null = null;
let moreOlderPostsAvailable = true;
let loadingOlderPosts = false;
onMount(async () => { onMount(async () => {
interval = setInterval(async () => { interval = setInterval(async () => {
@ -42,6 +44,7 @@ onMount(async () => {
}); });
async function loadOlderPosts() { async function loadOlderPosts() {
loadingOlderPosts = true;
const params = new URLSearchParams(); const params = new URLSearchParams();
if (data.posts.length > 0) { if (data.posts.length > 0) {
params.set('before', data.posts[data.posts.length - 1].created_at); params.set('before', data.posts[data.posts.length - 1].created_at);
@ -57,9 +60,14 @@ async function loadOlderPosts() {
return arr.map(mapObj => mapObj.url).indexOf(obj.url) === index; return arr.map(mapObj => mapObj.url).indexOf(obj.url) === index;
}); });
data.posts = filteredPosts; data.posts = filteredPosts;
moreOlderPostsAvailable = true;
} else {
moreOlderPostsAvailable = false;
} }
loadingOlderPosts = false;
}) })
.catch(e => { .catch(e => {
loadingOlderPosts = false;
// TODO: Show error in UI // TODO: Show error in UI
console.error('Error loading older posts', e); console.error('Error loading older posts', e);
}); });
@ -80,7 +88,10 @@ async function loadOlderPosts() {
{#each data.posts as post (post.url)} {#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}/> <LoadMoreComponent
on:loadOlderPosts={loadOlderPosts}
moreAvailable={moreOlderPostsAvailable}
isLoading={loadingOlderPosts}/>
</div> </div>
<div></div> <div></div>
</div> </div>
@ -88,6 +99,7 @@ async function loadOlderPosts() {
.posts { .posts {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center;
} }
.post { .post {
width: 100%; width: 100%;