|
1 | 1 | <script lang="ts">
|
| 2 | + import { Post } from '$lib/fragments'; |
| 3 | + import { dummyPosts } from '$lib/dummyData'; |
| 4 | + import { onMount } from 'svelte'; |
| 5 | +
|
| 6 | + type PostData = { |
| 7 | + id: number; |
| 8 | + avatar: string; |
| 9 | + username: string; |
| 10 | + imgUri: string; |
| 11 | + postAlt: string; |
| 12 | + text: string; |
| 13 | + time: string; |
| 14 | + count: { |
| 15 | + likes: number; |
| 16 | + comments: number; |
| 17 | + }; |
| 18 | + callback: { |
| 19 | + like: () => void; |
| 20 | + comment: () => void; |
| 21 | + menu: () => void; |
| 22 | + }; |
| 23 | + }; |
| 24 | +
|
| 25 | + let listElement: HTMLElement; |
| 26 | + let visiblePosts: PostData[] = $state([]); |
| 27 | + let maxVisiblePosts = $state(20); |
| 28 | + const batchSize = 10; |
| 29 | + let currentIndex = $state(0); |
| 30 | + let loading = $state(false); |
| 31 | +
|
| 32 | + const loadMore = () => { |
| 33 | + if (loading || currentIndex >= dummyPosts.length) return; |
| 34 | + loading = true; |
| 35 | + setTimeout(() => { |
| 36 | + const nextBatch = dummyPosts.slice(currentIndex, currentIndex + batchSize); |
| 37 | + visiblePosts = [...visiblePosts, ...nextBatch]; |
| 38 | + if (visiblePosts.length > maxVisiblePosts) { |
| 39 | + visiblePosts = visiblePosts.slice(visiblePosts.length - maxVisiblePosts); |
| 40 | + } |
| 41 | + currentIndex += batchSize; |
| 42 | + loading = false; |
| 43 | + }, 500); |
| 44 | + }; |
| 45 | +
|
| 46 | + const onScroll = () => { |
| 47 | + if (listElement.scrollTop + listElement.clientHeight >= listElement.scrollHeight) |
| 48 | + loadMore(); |
| 49 | + }; |
| 50 | +
|
| 51 | + $effect(() => { |
| 52 | + listElement.addEventListener('scroll', onScroll); |
| 53 | + return () => listElement.removeEventListener('scroll', onScroll); |
| 54 | + }); |
| 55 | +
|
| 56 | + onMount(() => { |
| 57 | + loadMore(); |
| 58 | + }); |
2 | 59 | </script>
|
| 60 | + |
| 61 | +<ul bind:this={listElement} class="hide-scrollbar h-[600px] overflow-auto"> |
| 62 | + {#each visiblePosts as post} |
| 63 | + <li class="mb-6"> |
| 64 | + <Post |
| 65 | + avatar={post.avatar} |
| 66 | + username={post.username} |
| 67 | + imgUri={post.imgUri} |
| 68 | + postAlt={post.postAlt} |
| 69 | + text={post.text} |
| 70 | + time={post.time} |
| 71 | + count={post.count} |
| 72 | + callback={post.callback} |
| 73 | + /> |
| 74 | + </li> |
| 75 | + {/each} |
| 76 | +</ul> |
| 77 | + |
| 78 | +{#if loading} |
| 79 | + <p class="my-4 text-center">Loading more posts…</p> |
| 80 | +{/if} |
0 commit comments