this repo has no description
16
fork

Configure Feed

Select the types of activity you want to include in your feed.

Style still WIP but much better now

astrra.space 037dea4e bf7fbdcb

verified
+113 -61
+7 -1
config.ts
··· 6 * The base URL of the PDS (Personal Data Server) 7 * @default "https://pds.witchcraft.systems" 8 */ 9 - static readonly PDS_URL: string = "https://pds.witchcraft.systems"; 10 11 /** 12 * The base URL of the frontend service for linking to replies 13 * @default "https://deer.social" 14 */ 15 static readonly FRONTEND_URL: string = "https://deer.social"; 16 }
··· 6 * The base URL of the PDS (Personal Data Server) 7 * @default "https://pds.witchcraft.systems" 8 */ 9 + static readonly PDS_URL: string = "https://ap.brid.gy"; 10 11 /** 12 * The base URL of the frontend service for linking to replies 13 * @default "https://deer.social" 14 */ 15 static readonly FRONTEND_URL: string = "https://deer.social"; 16 + 17 + /** 18 + * Maximum number of posts to fetch from the PDS per user 19 + * @default 10 20 + */ 21 + static readonly MAX_POSTS_PER_USER: number = 1; 22 }
+29 -5
src/App.svelte
··· 14 <div id="Account"> 15 <h1 id="Header">ATProto PDS</h1> 16 <p>Home to {accountsData.length} accounts</p> 17 {#each accountsData as accountObject} 18 <AccountComponent account={accountObject} /> 19 {/each} 20 </div> 21 {:catch error} 22 <p>Error: {error.message}</p> ··· 26 <p>Loading...</p> 27 {:then postsData} 28 <div id="Feed"> 29 {#each postsData as postObject} 30 <PostComponent post={postObject as Post} /> 31 {/each} 32 </div> 33 {/await} 34 </div> ··· 48 } 49 #Feed { 50 width: 65%; 51 - height: 80vh; 52 overflow-y: scroll; 53 padding: 20px; 54 } 55 #Account { 56 width: 35%; 57 height: 80vh; 58 overflow-y: scroll; 59 - padding: 20px; 60 - background-color: #070311; 61 - 62 - border-radius: 10px; 63 } 64 #Header { 65 text-align: center; 66 font-size: 2em;
··· 14 <div id="Account"> 15 <h1 id="Header">ATProto PDS</h1> 16 <p>Home to {accountsData.length} accounts</p> 17 + <div id="accountsList"> 18 {#each accountsData as accountObject} 19 <AccountComponent account={accountObject} /> 20 {/each} 21 + </div> 22 </div> 23 {:catch error} 24 <p>Error: {error.message}</p> ··· 28 <p>Loading...</p> 29 {:then postsData} 30 <div id="Feed"> 31 + <div id="spacer"></div> 32 {#each postsData as postObject} 33 <PostComponent post={postObject as Post} /> 34 {/each} 35 + <div id="spacer"></div> 36 </div> 37 {/await} 38 </div> ··· 52 } 53 #Feed { 54 width: 65%; 55 + height: 100vh; 56 overflow-y: scroll; 57 padding: 20px; 58 + padding-bottom: 0; 59 + padding-top: 0; 60 + margin-top: 0; 61 + margin-bottom: 0; 62 + } 63 + #spacer { 64 + padding: 0; 65 + margin: 0; 66 + height: 10vh; 67 + width: 100%; 68 } 69 #Account { 70 width: 35%; 71 + display: flex; 72 + flex-direction: column; 73 + border: 1px solid #8054f0; 74 + background-color: #0d0620; 75 height: 80vh; 76 + padding: 20px; 77 + } 78 + #accountsList { 79 + display: flex; 80 + flex-direction: column; 81 overflow-y: scroll; 82 + height: 100%; 83 + width: 100%; 84 + padding: 0px; 85 + margin: 0px; 86 } 87 + 88 #Header { 89 text-align: center; 90 font-size: 2em;
+23 -4
src/app.css
··· 6 ::-webkit-scrollbar { 7 width: 0px; 8 background: transparent; 9 } 10 - 11 * { 12 - scrollbar-width: thin; 13 scrollbar-color: transparent transparent; 14 -ms-overflow-style: none; /* IE and Edge */ 15 -webkit-overflow-scrolling: touch; ··· 45 46 #app { 47 max-width: 1400px; 48 - margin: 0 auto; 49 - padding: 2rem; 50 text-align: center; 51 } 52
··· 6 ::-webkit-scrollbar { 7 width: 0px; 8 background: transparent; 9 + padding: 0; 10 + margin: 0; 11 } 12 + ::-webkit-scrollbar-thumb { 13 + background: transparent; 14 + border-radius: 0; 15 + } 16 + ::-webkit-scrollbar-track { 17 + background: transparent; 18 + border-radius: 0; 19 + } 20 + ::-webkit-scrollbar-corner { 21 + background: transparent; 22 + border-radius: 0; 23 + } 24 + ::-webkit-scrollbar-button { 25 + background: transparent; 26 + border-radius: 0; 27 + } 28 * { 29 + scrollbar-width: none; 30 scrollbar-color: transparent transparent; 31 -ms-overflow-style: none; /* IE and Edge */ 32 -webkit-overflow-scrolling: touch; ··· 62 63 #app { 64 max-width: 1400px; 65 + margin: 0; 66 + padding: 0; 67 + margin-left: auto; 68 + margin-right: auto; 69 text-align: center; 70 } 71
+38 -39
src/lib/AccountComponent.svelte
··· 1 <script lang="ts"> 2 - import type { AccountMetadata } from "./pdsfetch"; 3 - const { account }: { account: AccountMetadata } = $props(); 4 - import { Config } from "../../config"; 5 </script> 6 7 <a id="link" href="{Config.FRONTEND_URL}/profile/{account.did}"> 8 - <div id="accountContainer"> 9 - {#if account.avatarCid} 10 - <img 11 - id="avatar" 12 - alt="avatar of {account.displayName}" 13 - src="{Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did={account.did}&cid={account.avatarCid}" 14 - /> 15 - {/if} 16 - <div id="accountName"> 17 - {account.displayName || account.handle || account.did} 18 - </div> 19 </div> 20 </a> 21 22 <style> 23 - #accountContainer { 24 - display: flex; 25 - text-align: start; 26 - align-items: center; 27 - background-color: #0d0620; 28 - padding: 4%; 29 - margin: 10px; 30 31 - /* round corners */ 32 - border-radius: 10px; 33 - } 34 - #accountName { 35 - margin-left: 10px; 36 - font-size: 0.9em; 37 - 38 - /* replace overflow with ellipsis */ 39 - overflow: hidden; 40 - text-overflow: ellipsis; 41 - white-space: nowrap; 42 - max-width: 80%; 43 - } 44 - #avatar { 45 - width: 50px; 46 - height: 50px; 47 - border-radius: 50%; 48 - } 49 </style>
··· 1 <script lang="ts"> 2 + import type { AccountMetadata } from "./pdsfetch"; 3 + const { account }: { account: AccountMetadata } = $props(); 4 + import { Config } from "../../config"; 5 </script> 6 7 <a id="link" href="{Config.FRONTEND_URL}/profile/{account.did}"> 8 + <div id="accountContainer"> 9 + {#if account.avatarCid} 10 + <img 11 + id="avatar" 12 + alt="avatar of {account.displayName}" 13 + src="{Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did={account.did}&cid={account.avatarCid}" 14 + /> 15 + {/if} 16 + <div id="accountName"> 17 + {account.displayName || account.handle || account.did} 18 </div> 19 + </div> 20 </a> 21 22 <style> 23 + #accountContainer { 24 + display: flex; 25 + text-align: start; 26 + align-items: center; 27 + background-color: #12082b; 28 + padding: 0px; 29 + margin-bottom: 15px; 30 + border: 1px solid #8054f0; 31 + } 32 + #accountName { 33 + margin-left: 10px; 34 + font-size: 0.9em; 35 36 + /* replace overflow with ellipsis */ 37 + overflow: hidden; 38 + text-overflow: ellipsis; 39 + white-space: nowrap; 40 + max-width: 80%; 41 + } 42 + #avatar { 43 + width: 50px; 44 + height: 50px; 45 + margin: 0px; 46 + border-right: #8054f0 1px solid; 47 + } 48 </style>
+15 -11
src/lib/PostComponent.svelte
··· 25 </div> 26 <div id="postContent"> 27 {#if post.replyingUri} 28 - <a 29 - id="replyingText" 30 - href="https://deer.social/profile/{post.replyingUri.repo}/post/{post 31 - .replyingUri.rkey}">replying to {post.replyingUri.repo}</a 32 - > 33 {/if} 34 - <p>{post.text}</p> 35 - 36 {#if post.quotingUri} 37 <a 38 id="quotingText" 39 - href="https://deer.social/profile/{post.quotingUri.repo}/post/{post 40 .quotingUri.rkey}">quoting {post.quotingUri.repo}</a 41 > 42 {/if} ··· 66 flex-direction: column; 67 border: 1px solid #8054f0; 68 background-color: black; 69 - margin-bottom: -1px; 70 } 71 #postHeader { 72 display: flex; ··· 78 height: fit-content; 79 border-bottom: 1px solid #8054f0; 80 font-weight: bold; 81 } 82 #postContent { 83 display: flex; ··· 86 padding: 10px; 87 background-color: #0d0620; 88 color: white; 89 } 90 #replyingText { 91 font-size: 0.7em; 92 - color: white; 93 margin: 0; 94 - margin-bottom: 10px; 95 padding: 0; 96 } 97 #postText { 98 margin: 0; 99 padding: 0; 100 } 101 #headerText { 102 margin-left: 10px; 103 font-size: 0.9em; 104 text-align: start; 105 } 106 #avatar { 107 width: 50px;
··· 25 </div> 26 <div id="postContent"> 27 {#if post.replyingUri} 28 + <a 29 + id="replyingText" 30 + href="{Config.FRONTEND_URL}/profile/{post.replyingUri.repo}/post/{post 31 + .replyingUri.rkey}">replying to {post.replyingUri.repo}</a 32 + > 33 {/if} 34 + <div id="postText">{post.text}</div> 35 {#if post.quotingUri} 36 <a 37 id="quotingText" 38 + href="{Config.FRONTEND_URL}/profile/{post.quotingUri.repo}/post/{post 39 .quotingUri.rkey}">quoting {post.quotingUri.repo}</a 40 > 41 {/if} ··· 65 flex-direction: column; 66 border: 1px solid #8054f0; 67 background-color: black; 68 + margin-bottom: 15px; 69 + overflow-wrap: break-word; 70 } 71 #postHeader { 72 display: flex; ··· 78 height: fit-content; 79 border-bottom: 1px solid #8054f0; 80 font-weight: bold; 81 + overflow-wrap: break-word; 82 } 83 #postContent { 84 display: flex; ··· 87 padding: 10px; 88 background-color: #0d0620; 89 color: white; 90 + overflow-wrap: break-word; 91 } 92 #replyingText { 93 font-size: 0.7em; 94 margin: 0; 95 padding: 0; 96 + padding-bottom: 5px; 97 } 98 #postText { 99 margin: 0; 100 + margin-bottom: 5px; 101 padding: 0; 102 } 103 #headerText { 104 margin-left: 10px; 105 font-size: 0.9em; 106 text-align: start; 107 + overflow-wrap: break-word; 108 + overflow: hidden; 109 } 110 #avatar { 111 width: 50px;
+1 -1
src/lib/pdsfetch.ts
··· 164 params: { 165 repo: did as At.Identifier, 166 collection: "app.bsky.feed.post", 167 - limit: 5, 168 }, 169 }); 170 return {
··· 164 params: { 165 repo: did as At.Identifier, 166 collection: "app.bsky.feed.post", 167 + limit: Config.MAX_POSTS_PER_USER, 168 }, 169 }); 170 return {