Skip to content

Commit 36f772a

Browse files
authored
feat/infinite-scroll (#170)
* feat/infinite-scroll * fix: aspect ratio of post * fix: bottom nav background
1 parent 8bd709f commit 36f772a

File tree

8 files changed

+107
-6
lines changed

8 files changed

+107
-6
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export const dummyPosts = Array.from({ length: 100 }, (_, i) => ({
2+
id: i + 1,
3+
avatar: 'https://www.gravatar.com/avatar/2c7d99fe281ecd3bcd65ab915bac6dd5?s=250',
4+
username: `user${i + 1}`,
5+
imgUri: 'https://picsum.photos/800',
6+
postAlt: 'Sample',
7+
text: `This is post number ${i + 1}. Loving how these shots came out! 📸`,
8+
time: `${i + 1} hours ago`,
9+
count: {
10+
likes: Math.floor(Math.random() * 500),
11+
comments: Math.floor(Math.random() * 200)
12+
},
13+
callback: {
14+
like: () => alert(`Like clicked on post ${i + 1}`),
15+
comment: () => alert(`Comment clicked on post ${i + 1}`),
16+
menu: () => alert(`Menu clicked on post ${i + 1}`)
17+
}
18+
}));

platforms/metagram/src/lib/fragments/BottomNav/BottomNav.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
<!-- svelte-ignore a11y_no_noninteractive_element_to_interactive_role -->
4141
<nav
4242
aria-label="Main navigation"
43-
class="fixed start-0 bottom-0 flex w-full items-center justify-between px-7 py-2 md:hidden"
43+
class="fixed start-0 bottom-0 flex w-full items-center justify-between bg-white px-7 py-2 md:hidden"
4444
role="tablist"
4545
>
4646
<button

platforms/metagram/src/lib/fragments/Header/Header.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
};
4545
4646
const classes = $derived({
47-
common: cn('flex items-center justify-between p-4'),
47+
common: cn('flex items-center justify-between py-4 px-0'),
4848
text: variantClasses[variant].text,
4949
background: variantClasses[variant].background
5050
});

platforms/metagram/src/lib/fragments/Post/Post.svelte

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@
5252
<HugeiconsIcon icon={MoreVerticalIcon} size={24} color="var(--color-black-500)" />
5353
</button>
5454
</div>
55-
<img src={imgUri} alt={postAlt ?? text} class="rounded-4xl" />
55+
<div class="overflow-hidden rounded-4xl">
56+
<img
57+
src={imgUri}
58+
alt={postAlt ?? text}
59+
class="aspect-[4/5] h-full w-full object-cover md:aspect-[16/9]"
60+
/>
61+
</div>
5662
<p class="text-black/80">{text}</p>
5763
<p class="text-black/60">{time}</p>
5864
<div class="flex w-full items-center justify-between">

platforms/metagram/src/lib/fragments/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export { default as Message } from './Message/Message.svelte';
88
export { default as ActionMenu } from './ActionMenu/ActionMenu.svelte';
99
export { default as Modal } from './Modal/Modal.svelte';
1010
export { default as SideBar } from './SideBar/SideBar.svelte';
11+
export { default as Post } from './Post/Post.svelte';

platforms/metagram/src/routes/(protected)/+layout.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
<main class="block h-[100dvh] grid-cols-[22vw_auto_31vw] md:grid">
2525
<SideBar profileSrc="https://picsum.photos/200" handlePost={async () => alert('adas')} />
26-
<section class="md:pt-10">
26+
<section class="mx-4 md:mx-8 md:pt-10">
2727
<Header variant="primary" {heading} />
2828
{@render children()}
2929
</section>
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +0,0 @@
1-
<script lang="ts">
2-
</script>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,80 @@
11
<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+
});
259
</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

Comments
 (0)