pds dash for shimaenaga.veryroundbird.house (based off of pds.witchcraft.systems)

Compare changes

Choose any two refs to compare.

+61
.tangled/workflows/build.yml
··· 1 + when: 2 + - event: ["push", "manual"] 3 + branch: ["main"] 4 + 5 + engine: "nixery" 6 + 7 + dependencies: 8 + nixpkgs: 9 + - deno 10 + - openssh 11 + - su 12 + 13 + steps: 14 + - name: "Pretend we have a real local user" 15 + command: | 16 + echo "🪶 pretend root is a real user" 17 + echo "root:x:0:0:System administrator:/root:/run/current-system/sw/bin/bash" >> /etc/passwd 18 + 19 + - name: "Copy config to server" 20 + command: | 21 + echo "🪶 copying config from secrets" 22 + echo "${CONFIG}" > config.ts 23 + 24 + - name: "Set up Deno" 25 + command: | 26 + echo "🪶 installing deno packages" 27 + deno install 28 + 29 + - name: "Build static files" 30 + command: | 31 + echo "🪶 building static files" 32 + deno run build 33 + 34 + - name: "SSH setup" 35 + command: | 36 + echo "🪶 setting up ssh connection" 37 + mkdir ~/.ssh 38 + echo "${SSH_KEY}" > ~/.ssh/id_tangledsh 39 + chmod 600 ~/.ssh/id_tangledsh 40 + cat > /etc/ssh/ssh_config << EOF 41 + Host deploy 42 + HostName ${SERVER_HOST} 43 + User ${SERVER_USER} 44 + IdentityFile ~/.ssh/id_tangledsh 45 + StrictHostKeyChecking no 46 + UserKnownHostsFile /dev/null 47 + BatchMode yes 48 + PasswordAuthentication no 49 + PubkeyAuthentication yes 50 + EOF 51 + chmod 600 /etc/ssh/ssh_config 52 + ssh-keyscan -H $SERVER_HOST >> ~/.ssh/known_hosts 53 + 54 + - name: "Deploy via SCP" 55 + command: | 56 + echo "🪶 deploying files via scp" 57 + scp -r ./dist/* deploy:/pds/caddy/etc/caddy/static 58 + 59 + - name: "Done!" 60 + command: | 61 + echo "🪶 all done!
-32
.tangled/workflows/pipeline.yml
··· 1 - when: 2 - - event: ["push", "manual"] 3 - branch: ["main"] 4 - engine: "nixery" 5 - dependencies: 6 - nixpkgs: 7 - - deno 8 - steps: 9 - - name: "Build static files" 10 - command: "deno run build" 11 - - name: "SSH setup" 12 - command: | 13 - mkdir ~/.ssh 14 - echo "${{secrets.SSH_KEY}}" > ~/.ssh/id_tangledsh 15 - chmod 600 ~/.ssh/id_tangledsh 16 - cat > ~/.ssh/config << EOF 17 - Host deploy 18 - HostName ${{ secrets.SERVER_HOST }} 19 - User ${{ secrets.SERVER_USER }} 20 - IdentityFile ~/.ssh/id_tangledsh 21 - StrictHostKeyChecking accept-new 22 - BatchMode yes 23 - PasswordAuthentication no 24 - PubkeyAuthentication yes 25 - EOF 26 - chmod 600 ~/.ssh/config 27 - ssh-keyscan -H ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts 28 - echo "🪶 deploying to shimaenaga pds" 29 - - name: "Deploy via SCP" 30 - run: scp -r ./dist/* deploy:/pds/caddy/webroot 31 - - name: "Done!" 32 - command: "echo \"🪶 all done!\""
+5 -2
README.md
··· 8 8 * Added some stuff in the backend code to also pull the user's description and banner to make the account cards fancier 9 9 * Changed font to Recursive Variable (waffling on changing this to space mono though and maybe using recursive just for the profile cards) 10 10 * Replaced favicon 11 - * Add guestbook functionality (see new config options) 12 - * Wrote deploy pipeline for tangled.sh 11 + * Ported in guestbook functionality from another PDS frontpage (see new config options) 12 + * Secret unique easter egg :) 13 + * Wrote deploy pipeline for tangled.sh (WORK IN PROGRESS help try #5 - changing ssh perms?) 14 + 15 + you can see it running at [my pds!](https://shimaenaga.veryroundbird.house) 13 16 14 17 # original readme below this line 15 18
public/fonts/spacemono-bold-webfont.woff2

This is a binary file and will not be displayed.

public/fonts/spacemono-bolditalic-webfont.woff2

This is a binary file and will not be displayed.

public/fonts/spacemono-italic-webfont.woff2

This is a binary file and will not be displayed.

public/fonts/spacemono-regular-webfont.woff2

This is a binary file and will not be displayed.

+71 -2
src/App.svelte
··· 1 1 <script lang="ts"> 2 2 import PostComponent from "./lib/PostComponent.svelte"; 3 + import GuestbookPostComponent from "./lib/GuestbookPostComponent.svelte"; 3 4 import AccountComponent from "./lib/AccountComponent.svelte"; 4 5 import InfiniteLoading from "svelte-infinite-loading"; 5 6 import { getNextPosts, Post, getAllMetadataFromPds, fetchGuestbookPosts } from "./lib/pdsfetch"; ··· 50 51 <main> 51 52 <div id="content"> 52 53 {#await accountsPromise} 53 - <p>Loading...</p> 54 + <div id="loadingbirds"> 55 + <div class="small"> 56 + <pre> 57 + █▓░░░░░░░░░▒ 58 + █▓▒ ░▒ 59 + ▓▒▒▒░ ▒ 60 + ▓▒░░░░ ░▓ 61 + █▒ ░░ ░ ░ ▓▒ ░█ 62 + ▓░ ░░ ▒▓░░▒▒░ ▒ 63 + ███████ ██▓▒░▒▒░ ░░░░ ░░░ ▒ 64 + █▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▒▒▓▒▒▒▓░ ▓ 65 + ███▓▒░░▒░░░░▓▓█▓▓▒░ ░ 66 + ▓ ░ 67 + █ ░ ▒ 68 + █░ ▒█ 69 + ▒ ▒ 70 + █▒ █ 71 + ▓ ░█ 72 + ▓▒ ░░ ░▒ 73 + ▓▒▒░░▒▓░ ░░░▒▒▓▓▒▓▓ 74 + █▓█▓▓█ ███▓█ 75 + ████ ████ 76 + </pre> 77 + </div> 78 + <div class="large"> 79 + <pre> 80 + ████▓▒░░░░░░░▒▓██ 81 + █▓░ ▒█ 82 + ██▓░ ▒█ 83 + ██▒ ▒█ 84 + ███▓▒░ ▓█ 85 + █▓░ ░ █ 86 + ██░ ░ ░█ 87 + █░ ▓ 88 + █▒ ▓ 89 + ██▒ ▒▓▓ █ 90 + █▒ ▓█ ░▒ ▒▓ ▓█ 91 + ██▒ ▒▓░ ░▒░░ ▓█ 92 + ███▒░ ░▒▒▒▒▒░ ▓█ 93 + █████ ██▓░ ░░░░ █ 94 + █▓▒░░░░░░▒▒▒▓▓██████████▓▓▒░ ░▒▒▒▒▒▒▓▒▒░ ░▒▒░ ░█ 95 + ██████▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░▒▒▒▒▓▒▒▓▓▓▓▒▒▒▒▒▒▓▒░░░▒▒▒░ ▒█ 96 + ███▓▓▒▒░░░░ ░░░▒▓▓▓▒▒▓▓▓▓▓▒░░▒▒▒▒░ █ 97 + ███▓▓▒ ▒▓▓▓▓▓▓▓█▓▒░░ █ 98 + █▓ ░▒▒▓▒░ ▓ 99 + █▓ ▓ 100 + █ █ 101 + █ ░█ 102 + █ ▓█ 103 + █░ ▒█ 104 + ▒ ▓█ 105 + ▓ █ 106 + █▒ ▒█ 107 + █▒ ▒█ 108 + █▓ ▒█ 109 + ██ ██ 110 + █▒ ▓█ 111 + ██░ ▒█ 112 + █░ ░▓█ 113 + █▓░ ▓▓▓░ ░▓▓▒ ░██ 114 + ███▓▒░ ▒▓▓▓ ▒▓▓▓▓▓▓▓████▓▓▓▓▒█ 115 + █▓██▓▓▓▓██ ████▓▓▓██ 116 + ██▓▓██ ██▓▓██ 117 + ███▓██ █▓▓▓██ 118 + ██████ ███████ 119 + </pre> 120 + </div> 121 + <p id="loadingText" data-text="pds is landing..." title="pds is landing...">pds is landing...</p> 122 + </div> 54 123 {:then accountsData} 55 124 <div id="account"> 56 125 <pre id="asciiart"> ··· 84 153 <div id="guestbookPosts"> 85 154 {#if guestbookPosts.length > 0} 86 155 {#each guestbookPosts as postObject} 87 - <PostComponent post={postObject as Post} /> 156 + <GuestbookPostComponent post={postObject.post} /> 88 157 {/each} 89 158 {:else} 90 159 <p class="noGuestbookPosts">No guestbook posts yet!</p>
+1 -1
src/lib/AccountComponent.svelte
··· 24 24 /> 25 25 {/if} 26 26 </div> 27 - <div class="accountTooltip" popover id="{account.handle.replace('.')}"> 27 + <div class="accountTooltip" popover id="{account.handle.replace('.', '')}"> 28 28 <div class="banner"> 29 29 <img class="bannerImg" src="{Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did={account.did}&cid={account.bannerCid}" alt="{account.displayName}'s banner" width="300" height="100" /> 30 30 <img class="avatarInsetImg" src="{Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did={account.did}&cid={account.avatarCid}" alt="{account.displayName}'s avatar" width="50" height="50" />
+92
src/lib/GuestbookPostComponent.svelte
··· 1 + <script lang="ts"> 2 + import { Post } from "./pdsfetch"; 3 + import { Config } from "../../config"; 4 + import { onMount } from "svelte"; 5 + import moment from "moment"; 6 + 7 + let { post }: { post: Post } = $props(); 8 + console.log(post); 9 + </script> 10 + 11 + <div class="postContainer"> 12 + <div class="postHeader"> 13 + {#if post.author.avatar} 14 + <img 15 + class="avatar" 16 + src="{post.author.avatar}" 17 + alt="avatar of {post.author.displayName}" 18 + /> 19 + {/if} 20 + <div class="headerText"> 21 + <a class="displayName" href="{Config.FRONTEND_URL}/profile/{post.author.did}">{post.author.displayName}</a> 22 + <p class="handle"> 23 + <a href="{Config.FRONTEND_URL}/profile/{post.author.handle}" 24 + >@{post.author.handle}</a 25 + > 26 + <a 27 + class="postLink" href="{Config.FRONTEND_URL}/profile/{post.author.did}/post/{post.record.id}" 28 + >{moment(post.record.createdAt).isBefore(moment().subtract(1, "month")) 29 + ? moment(post.record.createdAt).format("MMM D, YYYY") 30 + : moment(post.record.createdAt).fromNow()}</a> 31 + </p> 32 + </div> 33 + </div> 34 + <div class="postContent"> 35 + {#if post.record.quote} 36 + <a 37 + class="quotingText" 38 + href="{Config.FRONTEND_URL}/profile/{post.record.quote.uri}/post/{post 39 + .quotingUri.rkey}">quoting {post.quotingUri.repo}</a 40 + > 41 + {/if} 42 + <div class="postText">{post.record.text}</div> 43 + {#if post.record.imagesCid && post.record.imagesCid.length > 0} 44 + <div id="carouselContainer"> 45 + <img 46 + class="embedImages" 47 + alt="Post Image {currentImageIndex + 1} of {post.record.imagesCid.length}" 48 + src="{Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did={post.record.author.did}&cid={post.record 49 + .imagesCid[currentImageIndex]}" 50 + /> 51 + 52 + {#if post.imagesCid.length > 1} 53 + <div class="carouselControls"> 54 + <button 55 + id="prevBtn" 56 + onclick={prevImage} 57 + disabled={currentImageIndex === 0}>←</button 58 + > 59 + <div class="carouselIndicators"> 60 + {#each post.record.imagesCid as _, i} 61 + <div 62 + class="indicator {i === currentImageIndex ? 'active' : ''}" 63 + ></div> 64 + {/each} 65 + </div> 66 + <button 67 + class="nextBtn" 68 + onclick={nextImage} 69 + disabled={currentImageIndex === post.imagesCid.length - 1} 70 + >→</button 71 + > 72 + </div> 73 + {/if} 74 + </div> 75 + {/if} 76 + {#if post.record.videosLinkCid} 77 + <!-- svelte-ignore a11y_media_has_caption --> 78 + <video 79 + class="embedVideo" 80 + src="{Config.PDS_URL}/xrpc/com.atproto.sync.getBlob?did={post.authorDid}&cid={post.videosLinkCid}" 81 + controls 82 + ></video> 83 + {/if} 84 + {#if post.gifLink} 85 + <img 86 + class="embedVideo" 87 + src="{post.record.gifLink}" 88 + alt="Post GIF" 89 + /> 90 + {/if} 91 + </div> 92 + </div>
+72 -4
themes/birdrights/theme.css
··· 1 1 @font-face { 2 2 font-family: "Recursive Variable"; 3 3 font-weight: 100 700; 4 - font-style: -5deg 5deg; 5 4 src: url(/fonts/Recursive_VF_1.085.woff2) format('woff2'); 6 5 } 7 6 7 + @font-face { 8 + font-family: "Space Mono"; 9 + font-weight: normal; 10 + font-style: normal; 11 + src: url(/fonts/spacemono-regular-webfont.woff2) format('woff2'); 12 + } 13 + 14 + @font-face { 15 + font-family: "Space Mono"; 16 + font-weight: bold; 17 + font-style: normal; 18 + src: url(/fonts/spacemono-bold-webfont.woff2) format('woff2'); 19 + } 20 + 21 + @font-face { 22 + font-family: "Space Mono"; 23 + font-weight: normal; 24 + font-style: italic; 25 + src: url(/fonts/spacemono-italic-webfont.woff2) format('woff2'); 26 + } 27 + 28 + @font-face { 29 + font-family: "Space Mono"; 30 + font-weight: bold; 31 + font-style: italic; 32 + src: url(/fonts/spacemono-bolditalic-webfont.woff2) format('woff2'); 33 + } 34 + 8 35 :root { 9 36 /* Color overrides, edit to whatever you want */ 10 37 --primary-h: 260; /* Hue */ ··· 34 61 min-width: 320px; 35 62 min-height: 100vh; 36 63 background-color: var(--background-color); 37 - font-family: "Recursive Variable"; 64 + font-family: "Recursive Variable", monospace; 38 65 font-size: var(--base-font-size); 39 66 color: var(--text-color); 40 67 border-color: var(--border-color); ··· 55 82 } 56 83 57 84 h1 { 85 + font-family: "Space Mono", monospace; 58 86 font-size: 2em; 59 87 line-height: 1.1; 60 88 margin-bottom: 0; ··· 300 328 background-color: transparent; 301 329 padding: 0; 302 330 position: relative; 331 + cursor: pointer; 303 332 } 304 333 305 334 .accountContainer { ··· 326 355 white-space: nowrap; 327 356 } 328 357 329 - .accountTooltip { 358 + .accountTooltip[popover] { 330 359 border: 1px var(--border-color) solid; 331 360 color: var(--text-color); 332 361 background-color: var(--content-background-color); ··· 400 429 padding: 10px; 401 430 gap: 10px; 402 431 z-index: 10; 432 + grid-template-rows: auto 1fr; 403 433 } 404 434 405 435 #guestbookContents:popover-open { ··· 413 443 /* Source Link */ 414 444 415 445 #footer { 416 - position: absolute; 446 + position: fixed; 417 447 bottom: 5px; 418 448 right: 5px; 419 449 z-index: 99; ··· 428 458 429 459 #footer:hover { 430 460 opacity: 1; 461 + } 462 + 463 + #loadingbirds { 464 + line-height: 1; 465 + text-align: center; 466 + width: 100%; 467 + } 468 + 469 + #loadingbirds pre { 470 + display: inline-block; 471 + margin: 0 auto; 472 + text-align: left; 473 + } 474 + 475 + #loadingbirds .small { 476 + display: none; 477 + } 478 + 479 + #loadingbirds #loadingText { 480 + font-family: "Space Mono", monospace; 481 + text-align: center; 482 + font-style: oblique 5deg; 483 + font-size: 2em; 484 + min-height: 1em; 485 + } 486 + 487 + @media screen and (max-width: 780px) { 488 + #loadingbirds .small { 489 + display: block; 490 + } 491 + 492 + #loadingbirds .large { 493 + display: none; 494 + } 495 + 496 + #loadingbirds #loadingText { 497 + font-size: 1.25em; 498 + } 431 499 } 432 500 433 501 /* Responsive Styling */