pds dash for shimaenaga.veryroundbird.house (based off of pds.witchcraft.systems)
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, fetchGuestbookPosts } from "./lib/pdsfetch"; 6 import { Config } from "../config"; 7 const accountsPromise = getAllMetadataFromPds(); 8 import { onMount } from "svelte"; 9 10 let posts: Post[] = []; 11 let guestbookPosts: Post[] = []; 12 13 let clickCounter = 0; 14 const birdbrain = async () => { 15 clickCounter++; 16 if (clickCounter >= 10) { 17 clickCounter = 0; 18 document.getElementById('birdbrain').showPopover(); 19 } 20 }; 21 22 onMount(() => { 23 // Fetch initial posts 24 getNextPosts().then((initialPosts) => { 25 posts = initialPosts; 26 }); 27 fetchGuestbookPosts().then((gbPosts) => { 28 console.log(gbPosts); 29 guestbookPosts = gbPosts; 30 }); 31 }); 32 // Infinite loading function 33 const onInfinite = ({ 34 detail: { loaded, complete }, 35 }: { 36 detail: { loaded: () => void; complete: () => void }; 37 }) => { 38 getNextPosts().then((newPosts) => { 39 console.log("Loading next posts..."); 40 if (newPosts.length > 0) { 41 posts = [...posts, ...newPosts]; 42 loaded(); 43 } else { 44 complete(); 45 } 46 }); 47 }; 48</script> 49 50<main> 51 <div id="content"> 52 {#await accountsPromise} 53 <p>Loading...</p> 54 {:then accountsData} 55 <div id="account"> 56 <pre id="asciiart"> 57 █▓░░░░░░░░░▒ 58 █▓▒ ░▒ 59 ▓▒▒▒░ ▒ 60 ▓▒░░░░ ░▓ 61 █▒ ░░ ░ ░ ▓▒ ░█ 62 ▓░ ░░ ▒▓░░▒▒░ ▒ 63███████ ██▓▒░▒▒░ ░░░░ ░░░ ▒ 64█▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▒▒▓▒▒▒▓░ ▓ 65 ███▓▒░░▒░░░░▓▓█▓▓▒░ ░ 66 ▓ ░ 67 █ ░ ▒ 68 █░ ▒█ 69 ▒ ▒ 70 █▒ █ 71 ▓ ░█ 72 ▓▒ ░░ ░▒ 73 ▓▒▒░░▒▓░ ░░░▒▒▓▓▒▓▓ 74 █▓█▓▓█ ███▓█ 75 ████ ████ 76 </pre> 77 <h1 onclick={birdbrain} id="header">shimaenaga pds</h1> 78 <p id="subtitle">a project of <a href="https://veryroundbird.house" target="_blank">veryroundbird.house</a></p> 79 {#if Config.SHOW_GUESTBOOK} 80 <div id="guestbook"> 81 <button type="button" id="guestbookBtn" popovertarget="guestbookContents">say hi!</button> 82 <div id="guestbookContents" popover> 83 <div id="signInfo">You can sign the guestbook <a href="{Config.GUESTBOOK_POST}" target="_blank">here</a>!</div> 84 <div id="guestbookPosts"> 85 {#if guestbookPosts.length > 0} 86 {#each guestbookPosts as postObject} 87 <PostComponent post={postObject as Post} /> 88 {/each} 89 {:else} 90 <p class="noGuestbookPosts">No guestbook posts yet!</p> 91 {/if} 92 </div> 93 </div> 94 </div> 95 {/if} 96 <p class="accountCount">{accountsData.length} birds nesting here</p> 97 <div id="accountsList"> 98 {#each accountsData as accountObject} 99 <AccountComponent account={accountObject} /> 100 {/each} 101 </div> 102 <footer id="footer">{@html Config.FOOTER_TEXT}</footer> 103 </div> 104 {:catch error} 105 <p>Error: {error.message}</p> 106 {/await} 107 108 <div id="feed"> 109 {#each posts as postObject} 110 <PostComponent post={postObject as Post} /> 111 {/each} 112 <InfiniteLoading on:infinite={onInfinite} distance={3000} /> 113 </div> 114 </div> 115 <div id="birdbrain" popover> 116 <iframe width="560" height="315" src="https://www.youtube.com/embed/0iVlSNpq8i8?si=Ao4bcr_4HIBqsBy2" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> 117 </div> 118</main>