this repo has no description
1<script lang="ts">
2 import PostComponent from "./lib/PostComponent.svelte";
3 import AccountComponent from "./lib/AccountComponent.svelte";
4 import InfiniteLoading from "svelte-infinite-loading";
5 import { getNextPosts, Post, getAllMetadataFromPds } from "./lib/pdsfetch";
6 import { Config } from "../config";
7 const accountsPromise = getAllMetadataFromPds();
8 import { onMount } from "svelte";
9
10 let posts: Post[] = [];
11
12 onMount(() => {
13 // Fetch initial posts
14 getNextPosts().then((initialPosts) => {
15 posts = initialPosts;
16 });
17 });
18 // Infinite loading function
19 const onInfinite = ({
20 detail: { loaded, complete },
21 }: {
22 detail: { loaded: () => void; complete: () => void };
23 }) => {
24 getNextPosts().then((newPosts) => {
25 console.log("Loading next posts...");
26 if (newPosts.length > 0) {
27 posts = [...posts, ...newPosts];
28 loaded();
29 } else {
30 complete();
31 }
32 });
33 };
34</script>
35
36<main>
37 <div id="Content">
38 {#await accountsPromise}
39 <p>Loading...</p>
40 {:then accountsData}
41 <div id="Account">
42 <h1 id="Header">ATProto PDS</h1>
43 <p>Home to {accountsData.length} accounts</p>
44 <div id="accountsList">
45 {#each accountsData as accountObject}
46 <AccountComponent account={accountObject} />
47 {/each}
48 </div>
49 <p>{@html Config.FOOTER_TEXT}</p>
50 </div>
51 {:catch error}
52 <p>Error: {error.message}</p>
53 {/await}
54
55 <div id="Feed" property="infinite-wrapper">
56 <div id="spacer"></div>
57 {#each posts as postObject}
58 <PostComponent post={postObject as Post} />
59 {/each}
60 <InfiniteLoading on:infinite={onInfinite} distance={3000} forceUseInfiniteWrapper=true />
61 <div id="spacer"></div>
62 </div>
63 </div>
64</main>
65
66<style>
67 /* desktop style */
68
69 #Content {
70 display: flex;
71 /* split the screen in half, left for accounts, right for posts */
72 width: 100%;
73 height: 100%;
74 flex-direction: row;
75 justify-content: space-between;
76 align-items: center;
77 background-color: var(--background-color);
78 color: var(--text-color);
79 }
80 #Feed {
81 width: 65%;
82 height: 100vh;
83 overflow-y: scroll;
84 padding: 20px;
85 padding-bottom: 0;
86 padding-top: 0;
87 margin-top: 0;
88 margin-bottom: 0;
89 }
90 #spacer {
91 padding: 0;
92 margin: 0;
93 height: 10vh;
94 width: 100%;
95 }
96 #Account {
97 width: 35%;
98 display: flex;
99 flex-direction: column;
100 border: 1px solid var(--border-color);
101 background-color: var(--content-background-color);
102 height: 80vh;
103 padding: 20px;
104 margin-left: 20px;
105 }
106 #accountsList {
107 display: flex;
108 flex-direction: column;
109 overflow-y: scroll;
110 height: 100%;
111 width: 100%;
112 padding: 0px;
113 margin: 0px;
114 }
115
116 #Header {
117 text-align: center;
118 font-size: 2em;
119 margin-bottom: 20px;
120 }
121
122 /* mobile style */
123 @media screen and (max-width: 600px) {
124 #Content {
125 flex-direction: column;
126 width: auto;
127 padding-left: 0px;
128 padding-right: 0px;
129 margin-top: 5%;
130 }
131 #Account {
132 width: 85%;
133 padding-left: 5%;
134 padding-right: 5%;
135 margin-bottom: 20px;
136 margin-left: 5%;
137 margin-right: 5%;
138 height: auto;
139 }
140 #Feed {
141 width: 95%;
142 margin: 0px;
143 margin-left: 10%;
144 margin-right: 10%;
145 padding: 0px;
146 height: auto;
147 }
148
149 #spacer {
150 height: 0;
151 }
152 }
153</style>