diff --git a/.vscode/settings.json b/.vscode/settings.json index ca64273..e369383 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -32,6 +32,5 @@ }, "prettier.requireConfig": true, "prettier.configPath": ".prettierrc.mjs", - "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true } diff --git a/src/components/AgeRestrictedModal.astro b/src/components/AgeRestrictedModal.astro index 19940a5..1d7392d 100644 --- a/src/components/AgeRestrictedModal.astro +++ b/src/components/AgeRestrictedModal.astro @@ -57,8 +57,8 @@ import { IconTriangleExclamation } from "./icons"; <script> const ageRestrictedModalSetup = () => { const modal = document.querySelector<HTMLElementTagNameMap["div"]>("div#modal-age-restricted"); - // Not an age-restricted page if (!modal) { + // Not an age-restricted page return; } if (modal !== document.querySelector("body>div#modal-age-restricted")) { diff --git a/src/components/ExternalPosts.astro b/src/components/ExternalPosts.astro new file mode 100644 index 0000000..bbbe1db --- /dev/null +++ b/src/components/ExternalPosts.astro @@ -0,0 +1,100 @@ +--- +import type { Posts } from "../content/config"; +import { t, type Lang } from "../i18n"; +import { IconEkasPortal, IconFurAffinity, IconInkbunny, IconSoFurry, IconWeasyl } from "./icons/brands"; + +type Props = { + lang: Lang; + posts?: Posts; +}; + +const { lang, posts } = Astro.props; +const { eka, furaffinity, inkbunny, sofurry, weasyl } = posts ?? {}; +const isVisible = eka || furaffinity || inkbunny || sofurry || weasyl; +--- + +{ + isVisible ? ( + <section id="external-posts-section" class="my-5 px-2 font-serif" aria-describedby="title-external-posts"> + <> + <h2 id="title-external-posts" class="py-2 font-serif text-xl font-semibold text-stone-800 dark:text-stone-100"> + {t(lang, "published_content/syndication_see_also_on")} + </h2> + <ul id="external-posts" class="flex flex-wrap justify-around"> + {eka ? ( + <li class="min-w-12 grow"> + <a + class="u-syndication text-link w-full" + href={eka.link} + target="_blank" + aria-label={t(lang, "published_content/syndication_eka")} + > + <IconEkasPortal class="mx-auto" width="2rem" height="2rem" /> + </a> + </li> + ) : null} + {furaffinity ? ( + <li class="min-w-12 grow"> + <a + class="u-syndication text-link w-full" + href={furaffinity.link} + target="_blank" + aria-label={t(lang, "published_content/syndication_furaffinity")} + > + <IconFurAffinity class="mx-auto" width="2rem" height="2rem" /> + </a> + </li> + ) : null} + {inkbunny ? ( + <li class="min-w-12 grow"> + <a + class="u-syndication text-link w-full" + href={inkbunny.link} + target="_blank" + aria-label={t(lang, "published_content/syndication_inkbunny")} + > + <IconInkbunny class="mx-auto" width="2rem" height="2rem" /> + </a> + </li> + ) : null} + {sofurry ? ( + <li class="min-w-12 grow"> + <a + class="u-syndication text-link w-full" + href={sofurry.link} + target="_blank" + aria-label={t(lang, "published_content/syndication_sofurry")} + > + <IconSoFurry class="mx-auto" width="2rem" height="2rem" /> + </a> + </li> + ) : null} + {weasyl ? ( + <li class="min-w-12 grow"> + <a + class="u-syndication text-link w-full" + href={weasyl.link} + target="_blank" + aria-label={t(lang, "published_content/syndication_weasyl")} + > + <IconWeasyl class="mx-auto" width="2rem" height="2rem" /> + </a> + </li> + ) : null} + </ul> + </> + </section> + ) : null +} + +<script> + import tippy from "tippy.js"; + import "tippy.js/dist/tippy.css"; + + const clipboardItems = document.querySelectorAll<HTMLElement>("ul#external-posts a[aria-label]"); + + tippy(clipboardItems, { + content: (el) => (el as HTMLElement).getAttribute("aria-label")!, + theme: "bm", + }); +</script> diff --git a/src/components/MastodonComments.astro b/src/components/MastodonComments.astro index 01d610e..7203230 100644 --- a/src/components/MastodonComments.astro +++ b/src/components/MastodonComments.astro @@ -8,9 +8,10 @@ type Props = { instance: string; user: string; postId: string; + blacklistedComments?: string[]; }; -const { link, instance, user, postId } = Astro.props; +const { link, instance, user, postId, blacklistedComments } = Astro.props; --- <section @@ -21,6 +22,7 @@ const { link, instance, user, postId } = Astro.props; data-instance={instance} data-user={user} data-post-id={postId} + data-blacklisted={(blacklistedComments ?? []).join(",")} > <h2 id="title-comments-section" class="py-2 font-serif text-xl font-semibold text-stone-800 dark:text-stone-100"> Comments @@ -45,7 +47,7 @@ const { link, instance, user, postId } = Astro.props; class="group mx-auto w-64 rounded-lg bg-bm-300 px-4 py-1 text-stone-800 disabled:bg-bm-400 dark:bg-green-800 dark:text-stone-100 dark:disabled:bg-green-900" id="load-comments-button" > - <span class="block underline group-disabled:hidden">Click to load comments</span> + <span class="block hover:underline group-focus:underline group-disabled:hidden">Click to load comments</span> <span class="hidden group-disabled:block"> <svg style={{ width: "1.25rem", height: "1.25rem", display: "inline" }} @@ -144,6 +146,7 @@ const { link, instance, user, postId } = Astro.props; reblogs_count: number; created_at: string; edited_at: string | null; + language: string | null; account: { username: string; acct: string; @@ -162,7 +165,7 @@ const { link, instance, user, postId } = Astro.props; descendants: Status[]; } - async function renderComments(section: Element, post: MastodonPost) { + async function renderComments(section: Element, post: MastodonPost, blacklistedComments: Set<string>) { const commentsDescription = section.querySelector<HTMLElementTagNameMap["p"]>("p#comments-description")!; const loadCommentsButton = section.querySelector<HTMLElementTagNameMap["button"]>("button#load-comments-button")!; try { @@ -198,6 +201,13 @@ const { link, instance, user, postId } = Astro.props; )!; data.descendants.forEach((comment) => { + if (blacklistedComments.has(comment.id)) { + return; + } + if (blacklistedComments.has(comment.in_reply_to_id)) { + blacklistedComments.add(comment.id); + return; + } const commentBox = commentTemplate.content.cloneNode(true) as DocumentFragment; commentBox.firstElementChild!.id = `comment-${comment.id}`; @@ -303,6 +313,8 @@ const { link, instance, user, postId } = Astro.props; if (!post.link || !post.instance || !post.user || !post.postId) { return; } + const blacklisted = commentSection.dataset.blacklisted; + const blacklistedComments = new Set(blacklisted ? blacklisted.split(",") : undefined); const loadCommentsButton = commentSection.querySelector<HTMLElementTagNameMap["button"]>("button#load-comments-button")!; loadCommentsButton.addEventListener( @@ -310,7 +322,7 @@ const { link, instance, user, postId } = Astro.props; (e) => { e.preventDefault(); loadCommentsButton.disabled = true; - renderComments(commentSection, post as MastodonPost); + renderComments(commentSection, post as MastodonPost, blacklistedComments); }, { once: true }, ); diff --git a/src/components/icons/brands/IconEkasPortal.astro b/src/components/icons/brands/IconEkasPortal.astro new file mode 100644 index 0000000..dfd61aa --- /dev/null +++ b/src/components/icons/brands/IconEkasPortal.astro @@ -0,0 +1,15 @@ +--- +import SVGIcon from "../SVGIcon.astro"; + +type Props = { + width: string; + height: string; + class?: string; +}; +--- + +<SVGIcon {...Astro.props} viewBox="0 0 64 64"> + <path + d="m 32.722,49.22 c 0.042,-0.098 2.462,-0.072 2.586,0.1 0.123,0.172 0.198,0.56 0.198,0.685 0,0.126 -2.513,0.126 -2.54,0.033 -0.028,-0.092 -0.286,-0.719 -0.244,-0.817 z M 23.158,-0.01 c -0.203,0.019 -0.403,0.076 -0.719,0.172 -0.63,0.193 -0.958,0.608 -1.978,1.508 -1.018,0.9 -2.66,2.249 -4.145,3.838 -1.484,1.59 -3.344,3.707 -4.646,5.762 -1.302,2.05 -2.003,3.729 -3.13,6.464 -1.129,2.738 -2.484,7.326 -3.435,10 -0.95,2.676 -1.352,3.194 -2.224,6.065 -0.874,2.87 -2.343,7.677 -2.73,11.213 -0.386,3.536 0.079,9.002 0.2,9.799 0.123,0.795 0.482,1.68 0.813,2.021 0.33,0.34 1.161,1.156 2.727,0.705 1.566,-0.452 5.828,-5.378 6.754,-7.047 0.596,-1.144 1.298,-1.828 1.888,-3.082 0.484,-1.031 0.845,-2.591 1.397,-3.857 0.419,-1.03 0.46,-2.239 0.502,-3.047 0.043,-0.81 0.518,-7.403 1.175,-10.445 0.527,-1.76 1.888,-5.43 2.668,-7.688 0.781,-2.258 1.467,-4.44 2.018,-5.863 0.552,-1.423 1.13,-2.204 1.451,-2.336 0.322,-0.131 0.628,0.218 0.748,0.371 0.12,0.154 3.473,4.336 3.574,4.576 0.101,0.24 -0.237,0.798 -0.687,1.166 -0.451,0.368 -2.8,1.888 -3.604,3.004 -0.803,1.117 -0.343,0.874 -1.212,2.932 -0.869,2.056 -3.428,6.613 -4.043,9.396 -0.617,2.783 -0.12,5.404 -0.22,6.08 -0.099,0.677 -0.143,0.837 -0.342,2.12 -0.198,1.284 0.222,2.497 0.528,2.562 0.306,0.065 0.491,-0.997 0.87,-1.854 0.377,-0.856 1.012,-1.722 2.37,-1.246 0.983,0.606 0.648,3.765 0.9,4.68 0.253,0.915 0.3,1.356 0.54,1.396 0.24,0.04 0.436,-0.705 0.644,-1.373 0.208,-0.669 0.476,-1.451 0.823,-1.302 0.347,0.15 2.135,1.568 2.32,2.273 0.185,0.705 0.198,1.93 0.453,1.986 0.255,0.057 0.74,-1.437 0.936,-1.929 0.195,-0.491 0.91,-0.752 1.32,-0.93 0.41,-0.178 0.258,0.903 0.884,1.283 0.347,0.21 0.989,0.887 1.268,1.516 0.225,0.505 0.328,1.269 0.48,1.268 0,0 0.569,-0.939 0.97,-1.006 0.4,-0.066 1.465,1.225 1.928,1.453 0.462,0.227 1.375,0.537 1.564,0.707 0.187,0.168 0.61,0.585 0.53,0.765 -0.08,0.182 -0.50439,0.457755 -1.109395,0.785821 -0.605005,0.328067 -2.284966,1.008178 -2.86944,1.215165 -0.584474,0.206987 -4.103324,0.255544 -4.632324,0.970545 -0.53,0.715 -0.679281,2.172808 -0.638962,3.232839 0.06552,1.722607 -0.810214,0.955141 -0.854138,2.642662 -0.01625,0.624199 0.218914,1.090968 0.53865,1.090968 H 48.242 c 1.3,0 0.105,-4.107 -0.398,-5.305 -0.503,-1.196 -1.129,-1.485 -1.42,-1.992 -0.29,-0.508 -0.395,-1.203 -0.44,-1.797 -0.043,-0.594 0.026,-2.27 0.153,-2.982 0.125,-0.71 0.854,-1.613 1.847,-1.598 0.994,0.016 0.857,2.607 1.17,4.48 0.315,1.873 1.53,9.194 2.041,9.194 H 61.287 C 62.994,62.364 63.734,59.92 64,57.134 V 40.514 C 64,35.88 63.802,32.961 63.266,29.344 62.729,25.728 61.173,21.781 60.336,18.836 59.499,15.889 58.816,13.904 58.26,11.662 57.703,9.42 57.525,6.792 56.957,5.406 56.388,4.022 56.107,3.296 55.201,2.75 54.294,2.203 53.178,2.006 52.127,1.979 c -1.05,-0.028 -2.507,-0.01 -3.482,0.5 -0.975,0.51 -1.265,0.915 -2.02,2.423 -0.755,1.507 -1.263,4.86 -1.615,6.768 -0.353,1.91 -0.066,3.887 -0.61,4.648 -0.544,0.762 -1.71,0.582 -2.02,0.202 -0.448622,-0.557624 -1.127331,-0.879854 -1.843,-0.875 -0.928,0.003 -1.364,0.975 -2.2,1.38 -0.834,0.406 -1.685,0.854 -2.32,0.608 -0.633,-0.247 -0.44,-0.884 -1.18,-0.973 -0.739,-0.089 -1.382,0.309 -1.636,0.62 -0.254,0.31 -0.533,1.417 -1.123,1.241 -0.59,-0.176 -0.441,-0.564 -1.244,-0.73 -0.803,-0.165 -0.726,-0.063 -1.18,0.146 -0.451,0.208 -0.313,0.356 -0.71,-0.103 -0.399,-0.46 0.023,-2.56 0,-2.928 C 28.921,14.538 26.157,8.226 25.831,7.72 25.506,7.215 25.821,4.786 25.787,4.096 25.753,3.406 25.825,2.722 25.611,1.871 25.397,1.021 24.55,0.18 23.895,0.055 23.567,-0.007 23.361,-0.028 23.158,-0.01 Z m 0.156,1.59 c 0.06593,0.00211 0.130958,0.015991 0.192,0.041 0.48,0.202 0.604,0.403 0.664,0.77 h 0.002 c 0.06,0.366 0.136,2.318 -0.092,2.796 -0.228,0.478 -3.453,7.08 -3.596,7.26 -0.142,0.18 -1.721,3.26 -2.328,4.75 -1.327,3.85 -3.615,10.209 -3.985,11.438 -0.712,1.976 -1.032,5.902 -1.56,9.821 -0.235,1.724 -0.186,2.824 -0.463,3.862 -0.275,1.037 -0.286,1.909 -1.056,2.075 C 10.32,44.558 9.985,44.113 9.494,42.586 9.004,41.059 9.338,37.743 9.396,36.196 9.454,34.649 9.583,34.356 9.162,33.773 8.741,33.19 8.092,32.853 7.291,32.713 6.489,32.571 5.674,32.865 5.337,32.442 5,32.02 7.532,25.457 8.589,22.742 c 1.057,-2.717 1.444,-4.706 2.337,-6.586 0.892,-1.88 1.862,-3.462 2.785,-4.857 0.924,-1.396 1.43,-2.05 2.644,-3.537 1.216,-1.488 3.57,-3.961 3.866,-4.24 0.295,-0.281 1.278,-1.199 1.656,-1.362 0.33,-0.141 0.964,-0.602 1.437,-0.58 z M 51.03,3.416 c 0.92,-0.067 1.922,0.128 2.62,0.455 0.929,0.436 1.357,1.794 1.652,2.678 0.295,0.885 1.088,5.282 1.511,6.69 0.423,1.407 1.193,4.054 1.57,5.503 0.379,1.45 0.823,3.322 1.112,4.528 0.288,1.204 1.337,4.106 1.819,7.324 0.032,0.7 0.111,1.025 0.11,1.308 -0.18,0.158 -3.777,1.153 -5.058,2.084 -1.28,0.931 -2.227,4.276 -2.474,6.164 -0.247,1.888 -0.184,2.448 -0.557,3.688 -0.371,1.24 -1.036,2.766 -1.695,3.664 -0.659,0.898 -2.552,1.268 -2.613,0.886 -0.062,-0.382 -0.573,-4.447 -0.694,-5.199 -0.121,-0.752 -1.774,-27.056 -1.914,-27.666 -0.14,-0.61 0.216,-5.148 0.613,-6.835 0.397,-1.69 0.277,-2.33 0.895,-3.202 0.617,-0.871 1.134,-1.564 2.226,-1.91 0.273,-0.086 0.571,-0.137 0.877,-0.16 z M 30.2,24.189 c 1.282,0.02 1.777,2.14 2.475,2.778 0.697,0.637 0.899,1.099 1.566,1.16 0.669,0.063 1.463,-0.908 1.867,-0.908 0.406,0 2.977,-0.883 3.293,-1.121 0.318,-0.24 0.773,-0.75 1.41,-0.846 0.637,-0.097 0.705,0.805 0.907,1.26 0.203,0.454 0.505,2.694 0.758,3.94 0.252,1.244 1.168,2.519 0.79,3.132 -0.379,0.612 -3.429,0.741 -4.005,0.684 -0.576,-0.06 -0.745,0.45 -0.557,0.894 0.189,0.444 4.26,-0.322 4.822,0.106 0.563,0.428 0.567,0.922 0.559,1.236 -0.008,0.314 -0.003,0.934 -0.137,1.113 -0.134,0.18 -0.71,0.004 -1.377,-0.174 -0.667,-0.178 -1.557,-0.182 -2.222,-0.152 -0.666,0.03 -1.259,-10e-4 -1.744,0.28 -0.486,0.279 -1.02,0.85 -1.008,1.236 0.009,0.387 0.083,0.53 0.484,0.535 0.4,0.006 0.878,-0.755 1.348,-0.877 0.47,-0.123 1.906,-0.197 1.906,-0.197 0,0 -0.133,1.302 -0.184,2.072 -0.05,0.77 -0.014,1.702 0.163,2.336 0.176,0.635 0.328,1.13 0.789,1.32 0.46,0.192 1.024,-0.177 1.324,-0.404 0.298,-0.228 0.614,-0.92 0.636,-1.123 0.023,-0.203 -0.117,-3.167 0.249,-3.205 0.364,-0.04 0.347,0.571 0.488,1.29 0.14,0.72 1.613,6.99 0.1,9.346 -1.514,2.358 -5.673,2.872 -6.44,2.909 -0.577227,0.02725 -1.155733,-0.0029 -1.727,-0.09 -0.44,-0.06 -0.802,-0.138 -1.556,-0.49 -0.754,-0.353 -1.77,-1.303 -2.838,-2.174 -1.07,-0.87 -2.549,-2.381 -3.28,-3.16 -0.73,-0.78 -1.988,-2.129 -2.425,-3.133 -0.437,-1.006 -1.172,-3.108 -1.172,-4.31 -0.002,-1.203 0.219,-4.653 0.496,-5.665 0.277,-1.012 -0.017,-1.137 0.637,-1.473 0.654,-0.337 1.789,0.118 2.377,0.272 0.588,0.154 0.889,0.564 1.181,0.287 0.292,-0.276 0.291,-0.68 -0.216,-1.18 -0.507,-0.499 -2.908,-0.474 -3.006,-0.722 -0.098,-0.248 0.014,-0.576 0.06,-0.815 0.047,-0.238 -0.063,-1.973 0.48,-3.088 0.542,-1.115 1.449,-2.899 2.73,-2.879 z m -1.664,10.35 c -0.424,0.013 -0.831,0.08 -1.064,0.156 -0.466,0.156 -0.483,0.165 -0.582,0.432 -0.1,0.268 -0.096,0.847 0.215,0.967 0.562,-0.229 1.457,-0.704 1.625,-0.399 0.05,0.61 -0.36,1.946 -0.297,2.739 0.063,0.791 0.252,1.612 0.529,1.945 0.278,0.333 0.259,0.345 0.53,0.252 0.27,-0.093 0.393,-0.415 0.505,-1.012 0.113,-0.596 0.04,-1.964 0.045,-2.323 0.005,-0.36 0.068,-0.95 0.068,-0.95 0,0 0.349,0.334 0.544,0.47 0.195,0.136 0.469,-0.498 0.347,-0.908 -0.12,-0.41 -0.717,-0.952 -1.307,-1.213 -0.295,-0.13 -0.734,-0.17 -1.158,-0.156 z m 14.651,4.19 c 0.276,0.21 0.087,1.287 0.08,1.71 -0.008,0.423 0.007,1.383 -0.143,1.723 -0.152,0.34 -0.231,0.572 -0.56,0.545 -0.329,-0.027 -0.43,-0.314 -0.534,-0.713 -0.105,-0.399 -0.066,-1.168 -0.004,-1.773 0.061,-0.606 -0.043,-1.45 0.382,-1.653 0.374,-0.178 0.585,0.015 0.779,0.161 z M 27.473023,60.42187 c -0.303402,-0.0485 -0.09884,-1.813772 0.387667,-2.468772 0.29743,-0.400445 1.004288,-0.447544 2.649391,-0.594811 1.045763,-0.09361 2.113151,-0.411545 1.877675,-0.138733 -0.235476,0.272812 -1.094922,0.993716 -1.609305,1.313219 -0.514383,0.319503 -3.002026,1.937602 -3.305428,1.889097 z M 43.662,56.931 c 0.24,0.013 0.486,0.07 0.734,0.187 0.995,0.473 1.468,0.868 1.913,1.979 0.444,1.108 1.157,3.391 0.732,3.736 -0.425,0.345 -6.892,0.276 -7.332,-0.227 -0.44,-0.502 -0.042,-1.703 0.28,-2.476 0.32,-0.773 1.19,-2.31 1.818,-2.643 0.47,-0.25 1.134,-0.596 1.855,-0.556 z" + ></path> +</SVGIcon> diff --git a/src/components/icons/brands/IconFurAffinity.astro b/src/components/icons/brands/IconFurAffinity.astro new file mode 100644 index 0000000..9fceda4 --- /dev/null +++ b/src/components/icons/brands/IconFurAffinity.astro @@ -0,0 +1,15 @@ +--- +import SVGIcon from "../SVGIcon.astro"; + +type Props = { + width: string; + height: string; + class?: string; +}; +--- + +<SVGIcon {...Astro.props} viewBox="0 0 64 64"> + <path + d="M26.197 62.886c-.26-.57-.257-1.057.007-1.817.2-.57.362-1.875.362-2.9 0-1.024.128-1.941.285-2.038 1.27-.785.657-4.073-1.004-5.388l-1.314-1.041.222.884c.399 1.59-.388 3.432-1.466 3.432-1.18 0-1.549-.907-1.142-2.812.472-2.215-.546-4.19-1.369-2.654-.22.412-.673.643-1.258.643-1.03 0-1.81-.724-1.457-1.352.129-.229-.546.325-1.5 1.23-.953.906-2.645 2.124-3.76 2.707-2.369 1.239-3.332 2.276-4.082 4.396-.985 2.787-1.11 2.997-1.972 3.325-1.23.467-2.955-.16-3.208-1.167-.407-1.62.63-3.175 4.858-7.278 2.49-2.416 2.904-2.757 4.02-3.309 1.626-.804 3.983-3.186 2.987-3.02-.701.118-1.058-.089-1.058-.612 0-.318.18-.77.402-1.004.332-.352.27-.357-.363-.031-1.122.579-1.68-.338-.99-1.628.747-1.395-1.864-1.486-3.832-.132-2.813 1.935-5.868 1.241-5.375-1.22.398-1.992 2.175-2.917 4.968-2.586 1.732.205 4.062-1.346 3.154-2.1-1.436-1.191-6.902-2.055-8.294-1.31-2.124 1.137-3.654-1.47-1.581-2.695.871-.515 1.05-.52 2.13-.07 1.503.629 2.804.626 4.032-.01.62-.32 1.319-.426 1.927-.293 1.982.436 2.909-.86 2.139-2.989-.354-.978-.33-1.146.223-1.551.482-.352.535-.54.237-.839-.212-.211-.385-.868-.385-1.458 0-.591-.304-1.485-.675-1.987-1.115-1.508-.449-2.277 1.972-2.277h1.918v-1.44c0-1.22-.134-1.523-.884-1.993-.486-.306-1.474-1.085-2.196-1.732-.72-.648-2.055-1.424-2.964-1.726-3.855-1.28-4.364-5.327-.67-5.327 1.56 0 5.525 2.526 6.935 4.418 1.123 1.507 1.414 1.718 2.077 1.512.649-.202 1.56.655 1.56 1.465 0 .779.845 1.608 1.637 1.608.536 0 .614-.197.54-1.367-.082-1.292-.038-1.368.804-1.399 1.486-.054 1.187-1.634-.896-4.727-1.851-2.749-1.46-5.423.652-4.46 1.095.498 1.822 1.763 2.417 4.2.357 1.466.686 2.158 1.058 2.23.83.16.692-1.731-.264-3.615-.442-.87-.805-1.81-.808-2.09-.003-.28-.435-1.232-.96-2.116-1.088-1.835-1.18-2.475-.445-3.085.71-.59 2.053.935 2.053 2.33 0 .538.204 1.362.453 1.83.248.47.688 1.505.978 2.301.809 2.227 3.578 5.132 4.148 4.352.286-.39.67-.532 1.125-.413 1.164.305 1.42-2.364.706-7.378C32.602.433 32.751 0 34.157 0c1.09 0 1.27.25 1.15 1.608-.19 2.131-.058 5.275.232 5.564.193.194.352.576.352.85 0 .767 1.65.618 2.492-.225.397-.398.94-.723 1.206-.723s1.005-.28 1.641-.62c2.394-1.284 3.58.705 1.918 3.216-1.041 1.573-1.093 1.35.7 3.044 1.122 1.06 1.699 1.392 2.171 1.25 1.491-.45 1.926-.324 2.031.586.151 1.312.953 1.102 2.78-.73 2.294-2.3 3.221-1.887 1.46.65-.308.441-.657 1.116-.775 1.497-.119.382-.427.87-.685 1.085-.724.6-.622 2.562.134 2.562.332 0 .783.217 1.004.482.225.272.926.482 1.607.482 2.043 0 2.49 1.51.833 2.814-.786.618-.463 1.366.59 1.366.82 0 1.287 1.245.706 1.887-.449.496-.436.584.135.94.346.217.63.268.63.113 0-.329 3.939-1.334 5.225-1.333.725 0 .884.144.884.794 0 1.21-.966 1.543-3.723 1.284-2.708-.253-3.146.194-1.54 1.575.684.588.794.876.578 1.512-.146.431-.245.869-.22.972.026.103-.126.19-.338.195-1.09.02-2.821 1.457-2.255 1.87.473.346.5.54.179 1.247-.288.631-.29.817-.006.758.692-.143.616.983-.111 1.66-1.071.998-1.026 1.956.102 2.181 1.026.206 2.19 1.61 2.19 2.642 0 .797-1.354.924-3.104.29-1.501-.542-1.744-.043-.48.988.777.635 1.043 1.087.962 1.638-.152 1.044-.655 1.125-1.602.258-1.926-1.763-2.055-1.789-1.227-.25.429.797 1.02 1.775 1.315 2.175.538.728.468 1.971-.132 2.368-.661.438-1.61-.196-2.176-1.453-.328-.726-1.033-1.827-1.568-2.446l-.974-1.125-.008 1.85-.008 1.85-1.045-.082c-1.913-.15-1.004 3.988 1.673 7.614 2.381 3.227 2.42 5.363.1 5.588-1.294.125-2.12-1.067-2.608-3.758-.456-2.518-2.838-7.082-4.068-7.794-2.097-1.215-3.449-.196-2.768 2.085 1.146 3.838 1.119 4.722-.162 5.305-1.593.726-2.054.058-2.054-2.974 0-2.659-.433-3.736-1.503-3.736-.18 0-.584-.285-.9-.633-.511-.565-.643-.583-1.234-.17-.363.256-.976.385-1.362.288-.917-.23-2.396 2.17-2.396 3.89 0 .642-.136 1.423-.302 1.733-.166.31-.375 1.741-.464 3.18-.234 3.792-2.028 5.593-3.14 3.152zM38.94 48.043c2.979-1.951 3.15-7.58.306-10.077-.683-.6-1.105-1.264-1.105-1.743 0-6.205-6.566-8.681-10.748-4.052-.842.932-1.543 1.355-2.663 1.606-3.005.673-4.574 2.26-5.255 5.317-.894 4.007 1.283 5.78 6.681 5.442 3.475-.218 4.882.271 6.538 2.272 1.251 1.511 4.764 2.206 6.246 1.235zm8.48-8.987c2.208-1.858 1.868-6.062-.683-8.444-2.214-2.068-6.94 3.056-5.991 6.493.696 2.522 4.629 3.672 6.674 1.951zm-23.706-6.441c2.343-1.212 2.512-5.785.304-8.256l-.9-1.008-1.443.551c-2.068.79-4.022 2.572-4.474 4.08-1.087 3.627 2.931 6.485 6.513 4.633zm18.185-3.055c3.839-1.455 4.88-8.123 1.93-12.358-2.445-3.508-6.237-.349-7.336 6.11-.75 4.401 1.973 7.548 5.406 6.248zm6.473-1.691c.072-.61-.045-.86-.402-.86-.349 0-.504.306-.504.992 0 1.23.757 1.12.906-.132zm-15.173-2.166c2.732-2.508 3.919-8.787 2.118-11.209-2.789-3.753-10.61 3.976-9.105 8.998.953 3.18 4.654 4.352 6.987 2.21zm-9.527-5.482c0-.457-.849-.33-1.283.193-.218.263-.297.733-.176 1.045.225.578 1.46-.468 1.46-1.238zm18.65-6.234c0-.821-.44-1.073-.814-.467-.267.433.05 1.27.482 1.27.182 0 .331-.361.331-.803zm-6.584-1.793c.116-.367.13-.75.029-.85-.268-.268-1.163.559-1.163 1.075 0 .695.898.517 1.134-.225zm17.27 46.245c-.512-.632-1.524-3.723-1.295-3.952.656-.656 3.148 1.338 3.148 2.52 0 1.223-1.245 2.185-1.853 1.432zm-20.976-1.864c0-.694 1.017-2.272 1.386-2.15.537.177.67 1.466.207 2.023-.445.536-1.593.627-1.593.127zM1.7 52.196c-.576-.576-.199-1.715.568-1.715.798 0 1.388.959.988 1.605-.226.366-1.229.437-1.556.11zm8.21-5.637c-.554-.555-.487-1.865.097-1.865.265 0 .482-.14.482-.31 0-.474 1.175-.999 1.745-.78.813.312.59 1.096-.642 2.257-1.326 1.25-1.187 1.193-1.682.698zm48.029-.441c-1.177-1.177-.24-2.489 1.284-1.795.943.43 1.031 1.501.161 1.967-.804.43-.847.425-1.445-.172zM5.799 22.585c-.539-.366-.766-1.669-.441-2.523.387-1.02 1.378-.985 2.214.077.864 1.1.89 2.369.05 2.369-.34 0-.81.07-1.045.157-.236.087-.586.05-.778-.08zm48.74-2.96c0-.934 1.221-1.5 1.86-.863.41.41.424.586.083.996-.615.742-1.942.65-1.942-.133zm2.686.14c-.212-.551.34-1.102 1.115-1.11.638-.008.32 1.415-.345 1.542a.716.716 0 0 1-.77-.431zM8.94 19.213c.073-.518.353-.753.986-.825.949-.11 1.195.466.499 1.162-.682.683-1.6.474-1.485-.337zm44.13-7.42c-.329-.857.458-2.197 1.226-2.088 1.012.145 1.121 1.207.197 1.918-.91.7-1.206.735-1.423.17zM38.392 5.736c-.523-1.57.417-2.74 1.784-2.22 1.267.482 1.14 1.544-.256 2.127-1.344.562-1.371.563-1.528.093z" + ></path> +</SVGIcon> diff --git a/src/components/icons/brands/IconInkbunny.astro b/src/components/icons/brands/IconInkbunny.astro new file mode 100644 index 0000000..7a5f4db --- /dev/null +++ b/src/components/icons/brands/IconInkbunny.astro @@ -0,0 +1,15 @@ +--- +import SVGIcon from "../SVGIcon.astro"; + +type Props = { + width: string; + height: string; + class?: string; +}; +--- + +<SVGIcon {...Astro.props} viewBox="0 0 72 72"> + <path + d="M58.914 44.015c-.247.468-1.187 1.528-1.95 1.98-1.493.873-1.984 1.014-1.65.48.299-.483-1.403-.035-2.613.696-.55.326-1.211.898-1.326.783-.388-.388-1.69 3.786-1.535 4.82.174 2.417-1.846 3.545-3.733 5.455-1.885 1.908-3.682 3.793-3.816 3.793-.134 0-.756-.771-2.183-2.496-3.132-3.781-4.04-5.785-4.088-8.04.07-.472 1.116-.812 1.943-1.045 1.046-.29 2.79-1.198 2.79-1.198s2.917-1.63 3.026-1.694c.684-.35 1.374-.929 1.755-1.268 1.093-.943 1.736-2.4 1.929-3.16.134-.536-.288-1.356-.756-2.11l-.66-1.14.813-3.384c.467-1.795.455-4.315 1.54-5.147 2.835-.935 5.735-5.197 8.36-9.084 4.032-5.97 5.191-10.89 3.14-13.33-1.568-1.86-3.662-1.506-10.12 1.713-2.213 1.104-5.978 3.183-8.363 4.618-2.385 1.438-4.386 2.57-4.437 2.519-.05-.055.13-1.459.401-3.121.755-4.594.97-9.542.503-11.495C37.381 1.068 36.273-.016 34.83 0c-.864.008-1.846.413-2.893 1.234-4.306 3.384-9.427 10.025-11.403 16.29-1.62 5.134-3.793 16.975-3.538 19.958.52 6.127.924 5.226-.33 7.368C13.137 50.87 11 59.585 11 67.936c0 3.744-.43 4.064.125 4.064h2.986c.444-.083.287-.795.444-5.393.196-5.765.79-9.322 2.342-14.018.849-2.57 3.149-7.487 4.092-8.737.16-.216.44-.381.46-.577.035-.32-.134-.74-.516-1.534-.57-1.182-.837-2.047-.837-5.317.173-3.352.232-3.984.845-5.364.126-.291.524-1.019.68-1.56.33-1.125.311-2.488.546-3.863 1.584-9.31 3.232-14.91 8.526-20.452 3.168-2.848 4.552-3.734 4.54 1.023.334 4-1.334 12.948-3.056 17.381-.519 1.337-1.179 2.638-1.123 2.693.255.326 3.547-.484 3.91-1.597.133-.405.174-.398.318-.376.143.021 1.478 1.026 1.921 1.131.495.11 1.828-.515 1.876-.715.046-.2-2.593-1.83-2.774-1.997-.034-.388-.099-.453-.015-.825.084-.372.14-.615.899-1.105.758-.49 16.982-10.218 19.577-10.27.94-.039 1.35 1.426 1.368 1.935.017.509.04 2.72-.999 4.24-1.038 1.521-8.414 11.11-9.282 11.873-.867.763-2.678.75-3.319.386s-3.705-1.568-3.437-1.069c.271.503 1.255 1.324 1.79 1.933.369.44.99 1.265 1.38 1.835l.585.998-1.65 7.365.758 1.113c.597 1.014.605 1.143.126 2.142-.236.479-1.026 1.245-1.706 1.93-.31.286-4.578 3.006-6.96 3.776-1.781.515-1.615.295-3.12-.008-1.506-.302-4.52-2.453-5.124-1.858-.604.596.877 1.813 1.328 1.988.45.174.61.564 1.328.859.501.216 1.186 1.002 1.221 1.486.031.633.055.525.094 1.126.095 3.914.833 5.966 3.942 12.862 1.207 2.677 2.29 5.247 2.41 5.715.14.562.11.845.542.845h1.963c.597 0-.059-1.753-2.244-6.626-3.474-7.758-4.613-11.628-2.877-9.005.62 1.03 2.13 3.055 3.352 4.493 4.453 5.247 5.384 7.306 4.39 9.688-.42 1.002-.594 1.45-.26 1.45h2.09c.448 0 .579-.137.898-.896.573-1.378 1.536-2.204.95-3.842l-.243-1.14 2.936-4.048c1.064-1.399 2.203-3.179 2.738-3.761.538-.582.664-.797.664-.797.495.24 2.253-.09 2.522-.351.268-.261-.632-.143-.749-.538-.102-.169.707-.677 1.422-.965 1.418-.57 2.842-2.264 2.932-2.975.245-.297.267.551.277.93-.024.628-1.583 2.249-2.043 3.22-.46.973-.692 1.46-.543 2.44.149.98 1.215 1.857 2.648 1.787 1.432-.07 2.275-.936 2.295-2.316.02-1.565-1.778-6.887-1.667-6.864.11.028.382-7.094.22-7.793-.162-.699-.437-.795-.437-.795zm-33.575-7.213c.008.425 1.333.585 1.44-.075.157-.99 1.24-1.77 2.004-1.707.764.061 1.194.103 1.556.815.363.713.14 1.378.24 1.654.102.276 1.16.317 1.227-.133.066-.451.319-2.732-.927-3.389-1.247-.657-2.26-.776-3.545-.294-1.286.482-2.019 1.863-1.995 3.13zm15.64 1.859c.066-.21.446-.797.856-.574.41.222.252.614.245.81-.007.195.68.652.798.415.118-.237.186-.63.191-.795.006-.166.081-.753-.226-1.053-.307-.3-.894-.548-1.583-.33-.69.217-1.111.871-1.195 1.15-.084.277.846.587.913.377zm-6.251-1.067s.998 1.791 1.358 2.158c.36.367 1.502.72 2.08.456.578-.263 1.245-1.528 1.276-1.775a136.192 136.192 0 0 1-4.714-.84zm-.063 5.955c-.837.182-2.516.256-3.887-.012-1.371-.271-2.343.357-2.013.676.668.637 1.955.795 2.753.906 1.268.173 2.766-.017 3.207-.085.44-.068 1.364-.557 1.482-.47.06.044.616.507 1.245.822.596.298 1.47.464 1.727.503.256.039.982-.631.795-.747-.188-.115-.727-.27-1.018-.367a4.407 4.407 0 0 1-1.13-.542c-.533-.351-1.057-.865-1.2-1.23-.144-.366-.389.024-.7.157-.412.177-.424.205-1.261.39zm15.387 14.486c-1.143 1.549-1.374 1.888-2.364 3.201-1.446 1.91-2.78 3.526-2.955 3.585-.177.058-.511-.19-.735-.55-.374-.602-.146-.956 2.542-3.946 1.154-1.29 1.563-1.734 2.73-3.012.252-.272.458-.51.59-.503.132.006.631.368.732.44.1.072-.145.329-.54.785zM20.637 68.697c-.146 2.28-.126 3.301.118 3.301h1.764c.181 0 .123-.427.13-.887.031-3.03.812-8.371 1.31-12.02.116-.793-.597-1.307-1.142-1.115-.543.192-1.968 7.365-2.18 10.721z" + ></path> +</SVGIcon> diff --git a/src/components/icons/brands/IconSoFurry.astro b/src/components/icons/brands/IconSoFurry.astro new file mode 100644 index 0000000..32703e9 --- /dev/null +++ b/src/components/icons/brands/IconSoFurry.astro @@ -0,0 +1,15 @@ +--- +import SVGIcon from "../SVGIcon.astro"; + +type Props = { + width: string; + height: string; + class?: string; +}; +--- + +<SVGIcon {...Astro.props} viewBox="0 0 64 64"> + <path + d="M16.998 56.139c-3.483-.313-6.077-1.151-8.817-2.85-1.2-.745-1.99-1.373-3.22-2.565-1.27-1.23-2.101-2.23-3.042-3.663C1.323 46.154.004 43.696 0 43.484c-.003-.127.642-.091 1.265.07.316.082.59.134.609.116.019-.019-.066-.356-.187-.75-.703-2.275-.741-5.302-.1-7.857.679-2.702 2.023-5.117 3.99-7.169l1-1.043.178.567c.098.311.18.697.184.856.004.159.034.29.067.29s.41-.214.839-.474c3.491-2.12 7.817-2.179 11.225-.154.818.486 2.199 1.744 2.774 2.528.545.742 1.16 2.037 1.461 3.08.431 1.489.534 3.07.317 4.867l-.052.428-.707-.185c-1.395-.363-3.021-.203-4.173.411-.818.437-1.795 1.463-2.194 2.306-.32.674-.34.79-.34 1.876 0 1.085.021 1.203.337 1.87.415.876 1.157 1.613 2.083 2.069.722.356 1.837.636 2.527.636 1.224 0 3.052-.707 4.125-1.596 1.722-1.427 2.622-3.392 2.738-5.979.126-2.809-.505-5.298-2.39-9.42-1.822-3.984-2.493-6.404-2.599-9.38-.047-1.327-.022-1.926.118-2.764.42-2.509 1.414-4.424 3.18-6.127 2.175-2.097 5.092-3.31 8.256-3.437 1.262-.05 2.372.037 3.056.241.138.041.18-.07.23-.611.094-1.003.13-1.059.533-.851 1.488.766 3.272 2.398 4.234 3.875 1.201 1.842 1.712 3.483 1.802 5.79.065 1.662-.025 2.381-.92 7.387-.766 4.282-.875 5.151-.878 7.034-.003 1.482.024 1.76.228 2.31.198.533.775 1.323.965 1.321.032 0 .246-.367.476-.816.76-1.484 2.01-3.227 3.211-4.478 1.323-1.376 2.578-2.318 4.01-3.01l1.006-.486-.208-.473c-.146-.332-.223-.795-.258-1.56l-.05-1.086.41.07c1.318.222 2.772.758 3.846 1.42.282.173.524.315.538.315.013 0 .033-.344.045-.764.01-.42.06-.873.11-1.006l.09-.243.646.432c.847.565 2.001 1.717 2.788 2.78.347.47.661.865.698.88.038.014.2-.227.361-.535.161-.308.43-.722.597-.92l.305-.361.321.702c1.306 2.858 1.648 8.456.85 13.93-.844 5.791-2.563 9.862-5.357 12.686-2.172 2.195-4.194 3.067-7.104 3.063-1.668-.002-2.857-.2-4.497-.747-1.439-.48-2.255-.873-3.407-1.639-.922-.612-2.01-1.65-1.907-1.818.087-.14.98-.44 1.32-.443.53-.003.57-.121.27-.797-1.435-3.23-1.511-7.903-.197-12.062.147-.466.228-.882.18-.925-.048-.042-.29-.155-.537-.25-1.532-.593-2.635-1.942-3.154-3.858-.153-.565-.185-1.116-.181-3.158.004-2.199.044-2.772.362-5.158.468-3.513.507-5.76.121-6.88-.694-2.01-2.422-3.286-4.155-3.069-1.851.232-3.602 2.117-3.965 4.27-.295 1.75.205 3.449 2.138 7.258 1.965 3.873 2.696 5.787 3.218 8.42.623 3.15.589 6.597-.091 9.26-1.628 6.378-6.329 10.363-13.474 11.424-1.344.2-4.718.285-6.158.156zm38.56-5.629c1.611-.75 3.426-3.418 4.488-6.598 1.291-3.866 1.285-8.376-.015-11.01-.432-.875-1.105-1.543-1.66-1.647-.81-.152-2.248.65-3.448 1.922-1.708 1.81-2.954 4.326-3.559 7.182-.318 1.505-.4 4.178-.17 5.572.39 2.366 1.245 3.993 2.402 4.57.69.343 1.238.346 1.961.01zm-42.375-7.5c.099-1.947.728-3.439 2.058-4.878 1.197-1.295 2.751-2.147 4.532-2.484.538-.101.962-.234.962-.3 0-.066-.094-.485-.208-.931-.487-1.904-1.661-3.363-3.396-4.22-1.314-.648-2.2-.823-3.87-.764-1.518.054-2.535.329-3.684.995-.964.56-2.384 1.997-2.976 3.014-.489.838-1.332 3.164-1.196 3.3.106.105 1.495-.15 1.873-.345.175-.091.342-.142.37-.114.028.028.155.692.282 1.475.127.783.253 1.446.281 1.474.028.027.642-.086 1.366-.252.724-.167 1.39-.305 1.479-.307.138-.004.156.142.119.988-.076 1.746.384 3.107 1.37 4.056.244.233.474.425.512.425.038 0 .095-.51.126-1.132z" + ></path> +</SVGIcon> diff --git a/src/components/icons/brands/IconWeasyl.astro b/src/components/icons/brands/IconWeasyl.astro new file mode 100644 index 0000000..3093a53 --- /dev/null +++ b/src/components/icons/brands/IconWeasyl.astro @@ -0,0 +1,15 @@ +--- +import SVGIcon from "../SVGIcon.astro"; + +type Props = { + width: string; + height: string; + class?: string; +}; +--- + +<SVGIcon {...Astro.props} viewBox="0 0 24 24"> + <path + d="M21.23 4.156a8.488 8.488 0 0 0-5.871-1.857c-3.766.243-6.324 2.662-7.364 6.481-1.28-1.224-1.892-3.238-2.093-5.54-1.02.215-1.658.702-2.233 1.237.445 2.316 1.802 4.015 3.264 5.158-2.559.317-5.99 2.442-6.771 4.904-.507 1.598.258 3.415 1.283 4.52 1.237 1.333 3.75 1.998 6.355 1.754.037.362-.104.536-.058.907 4.067-.306 7.174-1.646 10.04-3.894 1.119-.877 2.659-2.037 3.756-3.227 1.101-1.192 2.296-2.578 2.443-4.52.21-2.79-1.236-4.694-2.751-5.923zm-1.434 10.938c-1.035 1.001-2.241 1.797-3.351 2.675-1.249-1.987-2.583-3.984-3.887-5.917.017 2.63.006 5.432.04 7.957-.78.381-1.789.558-2.744.763-1.935-2.917-3.968-5.99-5.961-8.908.693-.447 1.627-.785 2.478-1.075 1.419 2.05 2.729 4.253 4.171 6.333.019-3.113-.009-6.673-.061-9.919a14.175 14.175 0 0 0 1.527-.434c1.813 2.721 3.553 5.628 5.464 8.359a547.35 547.35 0 0 1-.018-9.768c.858-.282 1.803-.535 2.669-.809.02 3.499-.338 7.128-.327 10.743z" + ></path> +</SVGIcon> diff --git a/src/components/icons/brands/index.ts b/src/components/icons/brands/index.ts new file mode 100644 index 0000000..699bf44 --- /dev/null +++ b/src/components/icons/brands/index.ts @@ -0,0 +1,5 @@ +export { default as IconEkasPortal } from "./IconEkasPortal.astro"; +export { default as IconFurAffinity } from "./IconFurAffinity.astro"; +export { default as IconInkbunny } from "./IconInkbunny.astro"; +export { default as IconSoFurry } from "./IconSoFurry.astro"; +export { default as IconWeasyl } from "./IconWeasyl.astro"; diff --git a/src/content/blog/drafts/.gitignore b/src/content/blog/drafts/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/src/content/blog/drafts/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/src/content/config.ts b/src/content/config.ts index a3f4d34..6013507 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -78,6 +78,14 @@ const websiteLinks = z.object({ return { link, username }; }), ), + sofurrybeta: z.object({ link: z.string().url(), username: z.string() }).or( + z.string().transform((link, ctx) => { + const { username } = parseRegex<{ username: string }>( + /^(?:https?:\/\/)?sofurrybeta.com\/u\/(?<username>[^\/]+)\/?$/, + )(link, ctx); + return { link, username }; + }), + ), mastodon: z .object({ link: z.string().url(), username: z.string().regex(/^[^@]+@[^@]+$/) }) .or( @@ -144,7 +152,6 @@ const publishedContent = z.object({ // Required parameters title: z.string(), authors: userList, - contentWarning: z.string().trim(), // Required parameters, but optional for drafts (isDraft === true) pubDate: z .date() @@ -154,10 +161,10 @@ const publishedContent = z.object({ tags: z.array(z.string()), // Optional parameters isDraft: z.boolean().default(false), + isAgeRestricted: z.boolean().default(true), relatedStories: z.array(reference("stories")).default([]), relatedGames: z.array(reference("games")).default([]), lang: lang, - copyrightedCharacters: copyrightedCharacters, series: reference("series").optional(), posts: z .object({ @@ -191,6 +198,18 @@ const publishedContent = z.object({ )(link, ctx); return { link, postId }; }), + sofurrybeta: z.string().transform((link, ctx) => { + const { postId } = parseRegex<{ postId: string }>( + /^(?:https?:\/\/)sofurrybeta\.com\/s\/(?<postId>[a-zA-Z0-9]+)\/?$/, + )(link, ctx); + return { link, postId }; + }), + itch: z.string().transform((link, ctx) => { + const { user, postId } = parseRegex<{ user: string; postId: string }>( + /^(?:https?:\/\/)(?<user>[a-z-]+)\.itch\.io\/(?<postId>[a-z0-9_-]+)\/?$/, + )(link, ctx); + return { link, user, postId }; + }), twitter: z.string().transform((link, ctx) => { const { user, postId } = parseRegex<{ user: string; postId: string }>( /^(?:https?:\/\/)(?:www\.)?(?:twitter\.com|x\.com)\/(?<user>[a-zA-Z0-9_-]+)\/status\/(?<postId>[1-9]\d*)\/?$/, @@ -212,6 +231,7 @@ const publishedContent = z.object({ }) .partial() .default({}), + blacklistedMastodonComments: z.array(z.string()).default([]), }); // Types @@ -232,17 +252,19 @@ const storiesCollection = defineCollection({ z .object({ // Required parameters, but optional for drafts (isDraft === true) + contentWarning: z.string().trim(), wordCount: z.number().int().optional(), thumbnail: image().optional(), // Optional parameters - shortTitle: z.string().optional(), - commissioners: userList.optional(), - requesters: userList.optional(), - summary: z.string().trim().optional(), thumbnailWidth: z.number().int().optional(), thumbnailHeight: z.number().int().optional(), prev: reference("stories").nullish(), next: reference("stories").nullish(), + copyrightedCharacters: copyrightedCharacters, + shortTitle: z.string().optional(), + commissioners: userList.optional(), + requesters: userList.optional(), + summary: z.string().trim().optional(), }) .and(publishedContent) .refine(({ isDraft, description }) => isDraft || description, `Missing "description" for published story`) @@ -253,7 +275,11 @@ const storiesCollection = defineCollection({ .refine(({ isDraft, wordCount }) => isDraft || wordCount, `Missing "wordCount" for published story`) .refine(({ isDraft, pubDate }) => isDraft || pubDate, `Missing "pubDate" for published story`) .refine(({ isDraft, thumbnail }) => isDraft || thumbnail, `Missing "thumbnail" for published story`) - .refine(({ isDraft, tags }) => isDraft || tags.length, `Missing "tags" for published story`), + .refine(({ isDraft, tags }) => isDraft || tags.length, `Missing "tags" for published story`) + .refine( + ({ posts, blacklistedMastodonComments }) => !blacklistedMastodonComments.length || posts.mastodon, + `Cannot include "blacklistedMastodonComments" without a Mastodon post`, + ), }); const gamesCollection = defineCollection({ @@ -262,6 +288,7 @@ const gamesCollection = defineCollection({ z .object({ // Required parameters, but optional for drafts (isDraft === true) + contentWarning: z.string().trim(), platforms: z.array(platform).default([]), thumbnail: image().optional(), // Optional parameters @@ -269,6 +296,7 @@ const gamesCollection = defineCollection({ thumbnailHeight: z.number().int().optional(), prev: reference("games").nullish(), next: reference("games").nullish(), + copyrightedCharacters: copyrightedCharacters, }) .and(publishedContent) .refine(({ isDraft, description }) => isDraft || description, `Missing "description" for published game`) @@ -276,7 +304,36 @@ const gamesCollection = defineCollection({ .refine(({ isDraft, platforms }) => isDraft || platforms.length, `Missing "platforms" for published game`) .refine(({ isDraft, pubDate }) => isDraft || pubDate, `Missing "pubDate" for published game`) .refine(({ isDraft, thumbnail }) => isDraft || thumbnail, `Missing "thumbnail" for published game`) - .refine(({ isDraft, tags }) => isDraft || tags.length, `Missing "tags" for published game`), + .refine(({ isDraft, tags }) => isDraft || tags.length, `Missing "tags" for published game`) + .refine( + ({ posts, blacklistedMastodonComments }) => !blacklistedMastodonComments.length || posts.mastodon, + `Cannot include "blacklistedMastodonComments" without a Mastodon post`, + ), +}); + +const blogCollection = defineCollection({ + type: "content", + schema: ({ image }) => + z + .object({ + // Required parameters, but optional for drafts (isDraft === true) + thumbnail: image().optional(), + // Optional parameters + summary: z.string().trim().optional(), + thumbnailWidth: z.number().int().optional(), + thumbnailHeight: z.number().int().optional(), + prev: reference("blog").nullish(), + next: reference("blog").nullish(), + }) + .and(publishedContent) + .refine(({ isDraft, description }) => isDraft || description, `Missing "description" for published story`) + .refine(({ isDraft, pubDate }) => isDraft || pubDate, `Missing "pubDate" for published story`) + .refine(({ isDraft, thumbnail }) => isDraft || thumbnail, `Missing "thumbnail" for published story`) + .refine(({ isDraft, tags }) => isDraft || tags.length, `Missing "tags" for published story`) + .refine( + ({ posts, blacklistedMastodonComments }) => !blacklistedMastodonComments.length || posts.mastodon, + `Cannot include "blacklistedMastodonComments" without a Mastodon post`, + ), }); // Data collections @@ -332,6 +389,7 @@ const tagCategoriesCollection = defineCollection({ export const collections = { stories: storiesCollection, games: gamesCollection, + blog: blogCollection, users: usersCollection, series: seriesCollection, "tag-categories": tagCategoriesCollection, diff --git a/src/content/stories/accommodation.md b/src/content/stories/accommodation.md index 0a1efdf..3ebdd19 100644 --- a/src/content/stories/accommodation.md +++ b/src/content/stories/accommodation.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245838/accommodation-vore-story inkbunny: https://inkbunny.net/s/3009993 sofurry: https://www.sofurry.com/view/1992347 + sofurrybeta: https://sofurrybeta.com/s/dmBBW6Zm tags: - anal vore - anthro predator diff --git a/src/content/stories/addictive-additions.md b/src/content/stories/addictive-additions.md index 0340e47..8a12cd5 100644 --- a/src/content/stories/addictive-additions.md +++ b/src/content/stories/addictive-additions.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245835/c-addictive-additions-vore-story inkbunny: https://inkbunny.net/s/3009992 sofurry: https://www.sofurry.com/view/1992344 + sofurrybeta: https://sofurrybeta.com/s/ZmM3E4q1 tags: - oral vore - anal vore @@ -30,6 +31,7 @@ tags: - semi-willing prey - similar size - implied perma endo + - endo trait theft - straight sex - gay sex - hyper diff --git a/src/content/stories/annivoresary.md b/src/content/stories/annivoresary.md index 5ae7d34..38fb640 100644 --- a/src/content/stories/annivoresary.md +++ b/src/content/stories/annivoresary.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245812/annivoresary-vore-story inkbunny: https://inkbunny.net/s/3009934 sofurry: https://www.sofurry.com/view/1992300 + sofurrybeta: https://sofurrybeta.com/s/3egLylPm tags: - oral vore - anthro predator diff --git a/src/content/stories/better-in-bully-batter.md b/src/content/stories/better-in-bully-batter.md index abbd9b3..238f6e9 100644 --- a/src/content/stories/better-in-bully-batter.md +++ b/src/content/stories/better-in-bully-batter.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245853/c-better-in-bully-batter-vore-story inkbunny: https://inkbunny.net/s/3010009 sofurry: https://www.sofurry.com/view/1992371 + sofurrybeta: https://sofurrybeta.com/s/dmW3GPwm tags: - cock vore - anthro predator @@ -27,6 +28,7 @@ tags: - unwilling prey - similar size - implied perma endo + - endo trait theft - straight sex - gay sex - orgy diff --git a/src/content/stories/big-haul.md b/src/content/stories/big-haul.md index 60f12f8..a5c4492 100644 --- a/src/content/stories/big-haul.md +++ b/src/content/stories/big-haul.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2326739/big-haul-vore-story inkbunny: https://inkbunny.net/s/3179339 sofurry: https://www.sofurry.com/view/2074207 + sofurrybeta: https://sofurrybeta.com/s/GnDLVoGn tags: - unbirth - anthro predator diff --git a/src/content/stories/birdroom.md b/src/content/stories/birdroom.md index ce1768a..07cafa7 100644 --- a/src/content/stories/birdroom.md +++ b/src/content/stories/birdroom.md @@ -18,6 +18,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245859/birdroom-vore-story inkbunny: https://inkbunny.net/s/3010032 sofurry: https://www.sofurry.com/view/1992379 + sofurrybeta: https://sofurrybeta.com/s/7ejYXvL1 tags: - Sam Brendan - Beetle diff --git a/src/content/stories/bladder-filler.md b/src/content/stories/bladder-filler.md index 9425763..0aa8b21 100644 --- a/src/content/stories/bladder-filler.md +++ b/src/content/stories/bladder-filler.md @@ -18,6 +18,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2322878/bladder-filler-vore-story inkbunny: https://inkbunny.net/s/3168729 sofurry: https://www.sofurry.com/view/2069991 + sofurrybeta: https://sofurrybeta.com/s/J1O5Z3zm tags: - Beetle - cock vore diff --git a/src/content/stories/bottom-of-the-food-chain.md b/src/content/stories/bottom-of-the-food-chain.md index 4de1990..f3d9ac4 100644 --- a/src/content/stories/bottom-of-the-food-chain.md +++ b/src/content/stories/bottom-of-the-food-chain.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2308019/bottom-of-the-food-chain-vore-story inkbunny: https://inkbunny.net/s/3130702 sofurry: https://www.sofurry.com/view/2054568 + sofurrybeta: https://sofurrybeta.com/s/Vm2b34Gm tags: - Muno - oral vore diff --git a/src/content/stories/butting-into-their-plans.md b/src/content/stories/butting-into-their-plans.md index bea9fdb..a0f078b 100644 --- a/src/content/stories/butting-into-their-plans.md +++ b/src/content/stories/butting-into-their-plans.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245850/butting-into-their-plans-vore-story inkbunny: https://inkbunny.net/s/3010005 sofurry: https://www.sofurry.com/view/1992365 + sofurrybeta: https://sofurrybeta.com/s/znJE5M3m tags: - anal vore - feral predator diff --git a/src/content/stories/delicacy-s-dare.md b/src/content/stories/delicacy-s-dare.md index 00bb4c7..3b793bd 100644 --- a/src/content/stories/delicacy-s-dare.md +++ b/src/content/stories/delicacy-s-dare.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245840/delicacy-s-dare-vore-story inkbunny: https://inkbunny.net/s/3009994 sofurry: https://www.sofurry.com/view/1992348 + sofurrybeta: https://sofurrybeta.com/s/V1YARGy1 tags: - oral vore - anthro predator diff --git a/src/content/stories/eggs-for-months.md b/src/content/stories/eggs-for-months.md index d70fd38..2000639 100644 --- a/src/content/stories/eggs-for-months.md +++ b/src/content/stories/eggs-for-months.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245808/eggs-for-months-vore-story inkbunny: https://inkbunny.net/s/3009928 sofurry: https://www.sofurry.com/view/1992262 + sofurrybeta: https://sofurrybeta.com/s/lmXB9VG1 tags: - sheath vore - feral predator diff --git a/src/content/stories/engaging-contacts.md b/src/content/stories/engaging-contacts.md index 8810056..32ba22f 100644 --- a/src/content/stories/engaging-contacts.md +++ b/src/content/stories/engaging-contacts.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2291372/engaging-contacts-vore-story inkbunny: https://inkbunny.net/s/3088451 sofurry: https://www.sofurry.com/view/2035092 + sofurrybeta: https://sofurrybeta.com/s/YnLrbBpe tags: - oral vore - unbirth diff --git a/src/content/stories/flavorful-favor.md b/src/content/stories/flavorful-favor.md index 3a890cf..f234fd4 100644 --- a/src/content/stories/flavorful-favor.md +++ b/src/content/stories/flavorful-favor.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245855/flavorful-favor-vore-story inkbunny: https://inkbunny.net/s/3010014 sofurry: https://www.sofurry.com/view/1992375 + sofurrybeta: https://sofurrybeta.com/s/WelWOaj1 tags: - Beetle - oral vore diff --git a/src/content/stories/for-the-night.md b/src/content/stories/for-the-night.md index 5f645df..12d5189 100644 --- a/src/content/stories/for-the-night.md +++ b/src/content/stories/for-the-night.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245830/for-the-night-vore-story inkbunny: https://inkbunny.net/s/3009989 sofurry: https://www.sofurry.com/view/1992339 + sofurrybeta: https://sofurrybeta.com/s/P1EMLv81 tags: - anal vore - anthro predator diff --git a/src/content/stories/gentle-and-cruel.md b/src/content/stories/gentle-and-cruel.md index 85898a7..ad36fc9 100644 --- a/src/content/stories/gentle-and-cruel.md +++ b/src/content/stories/gentle-and-cruel.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2320112/gentle-and-cruel-vore-story inkbunny: https://inkbunny.net/s/3161450 sofurry: https://www.sofurry.com/view/2066780 + sofurrybeta: https://sofurrybeta.com/s/3egLyEdm tags: - oral vore - anthro predator diff --git a/src/content/stories/hate-to-sea-it.md b/src/content/stories/hate-to-sea-it.md index d254dfd..ff5fb7a 100644 --- a/src/content/stories/hate-to-sea-it.md +++ b/src/content/stories/hate-to-sea-it.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245852/hate-to-sea-it-vore-story inkbunny: https://inkbunny.net/s/3010007 sofurry: https://www.sofurry.com/view/1992369 + sofurrybeta: https://sofurrybeta.com/s/pnGE786e tags: - unbirth - feral predator diff --git a/src/content/stories/hungry-for-love.md b/src/content/stories/hungry-for-love.md index cd8bc25..bcfabb7 100644 --- a/src/content/stories/hungry-for-love.md +++ b/src/content/stories/hungry-for-love.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245845/hungry-for-love-vore-story inkbunny: https://inkbunny.net/s/3010001 sofurry: https://www.sofurry.com/view/1992358 + sofurrybeta: https://sofurrybeta.com/s/pnGE787e tags: - oral vore - feral predator diff --git a/src/content/stories/hyper-hunger.md b/src/content/stories/hyper-hunger.md index 746769b..1ed13a4 100644 --- a/src/content/stories/hyper-hunger.md +++ b/src/content/stories/hyper-hunger.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245818/hyper-hunger-vore-story inkbunny: https://inkbunny.net/s/3009945 sofurry: https://www.sofurry.com/view/1992317 + sofurrybeta: https://sofurrybeta.com/s/JewQ7gYn tags: - oral vore - anthro predator diff --git a/src/content/stories/insistence-and-assistance.md b/src/content/stories/insistence-and-assistance.md index d2e1b6b..4edeb9c 100644 --- a/src/content/stories/insistence-and-assistance.md +++ b/src/content/stories/insistence-and-assistance.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245823/insistence-and-assistance-vore-story inkbunny: https://inkbunny.net/s/3009949 sofurry: https://www.sofurry.com/view/1992324 + sofurrybeta: https://sofurrybeta.com/s/A1pxJED1 tags: - oral vore - anthro predator diff --git a/src/content/stories/lactation-action.md b/src/content/stories/lactation-action.md index f90f218..0f827fc 100644 --- a/src/content/stories/lactation-action.md +++ b/src/content/stories/lactation-action.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245829/lactation-action-vore-story inkbunny: https://inkbunny.net/s/3009986 sofurry: https://www.sofurry.com/view/1992335 + sofurrybeta: https://sofurrybeta.com/s/0mvw0ZQn tags: - nipple vore - oral vore diff --git a/src/content/stories/latest-catch.md b/src/content/stories/latest-catch.md index 7e7df5e..47f2322 100644 --- a/src/content/stories/latest-catch.md +++ b/src/content/stories/latest-catch.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245828/latest-catch-vore-story inkbunny: https://inkbunny.net/s/3009984 sofurry: https://www.sofurry.com/view/1992331 + sofurrybeta: https://sofurrybeta.com/s/rn6Jyzpn tags: - cock vore - anthro predator diff --git a/src/content/stories/never-too-late.md b/src/content/stories/never-too-late.md index a4ee1d5..0c8178f 100644 --- a/src/content/stories/never-too-late.md +++ b/src/content/stories/never-too-late.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245821/never-too-late-vore-story inkbunny: https://inkbunny.net/s/3009947 sofurry: https://www.sofurry.com/view/1992320 + sofurrybeta: https://sofurrybeta.com/s/5nz8gOle tags: - cock vore - anthro predator diff --git a/src/content/stories/noble-fire.md b/src/content/stories/noble-fire.md index b7d32d4..a63f1c3 100644 --- a/src/content/stories/noble-fire.md +++ b/src/content/stories/noble-fire.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2305403/noble-fire-vore-story inkbunny: https://inkbunny.net/s/3124162 sofurry: https://www.sofurry.com/view/2051777 + sofurrybeta: https://sofurrybeta.com/s/lmXB9qy1 tags: - oral vore - anthro predator diff --git a/src/content/stories/overzealous-zenko.md b/src/content/stories/overzealous-zenko.md index 15e4033..f9baa7a 100644 --- a/src/content/stories/overzealous-zenko.md +++ b/src/content/stories/overzealous-zenko.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2291367/r-overzealous-zenko-vore-story inkbunny: https://inkbunny.net/s/3088442 sofurry: https://www.sofurry.com/view/2035087 + sofurrybeta: https://sofurrybeta.com/s/Xek5wP5n tags: - chest maw vore - taur predator diff --git a/src/content/stories/part-of-the-show.md b/src/content/stories/part-of-the-show.md index 557fb47..6d75547 100644 --- a/src/content/stories/part-of-the-show.md +++ b/src/content/stories/part-of-the-show.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2257653/part-of-the-show-vore-story inkbunny: https://inkbunny.net/s/3030429 sofurry: https://www.sofurry.com/view/2001881 + sofurrybeta: https://sofurrybeta.com/s/r17DQXBe tags: - Sam Brendan - anthro predator diff --git a/src/content/stories/pet-sit-saturday.md b/src/content/stories/pet-sit-saturday.md index d4f0417..ad4e42f 100644 --- a/src/content/stories/pet-sit-saturday.md +++ b/src/content/stories/pet-sit-saturday.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245810/pet-sit-saturday-vore-story inkbunny: https://inkbunny.net/s/3009931 sofurry: https://www.sofurry.com/view/1992266 + sofurrybeta: https://sofurrybeta.com/s/qmywZNW1 tags: - anal vore - anthro predator diff --git a/src/content/stories/playing-it-safe.md b/src/content/stories/playing-it-safe.md index 0b956c0..fb5bc2c 100644 --- a/src/content/stories/playing-it-safe.md +++ b/src/content/stories/playing-it-safe.md @@ -16,6 +16,7 @@ posts: furaffinity: https://www.furaffinity.net/view/57675502/ inkbunny: https://inkbunny.net/s/3391838 sofurry: https://www.sofurry.com/view/2161474 + sofurrybeta: https://sofurrybeta.com/s/dmBBkvXm weasyl: https://www.weasyl.com/~badmanners/submissions/2401625/playing-it-safe twitter: https://x.com/BadManners__/status/1821526198150680589 bluesky: https://bsky.app/profile/badmanners.xyz/post/3kz7gvvwyvt2c diff --git a/src/content/stories/reaching-for-the-full-moon.md b/src/content/stories/reaching-for-the-full-moon.md index 0e375bb..a09fc5d 100644 --- a/src/content/stories/reaching-for-the-full-moon.md +++ b/src/content/stories/reaching-for-the-full-moon.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245847/reaching-for-the-full-moon-vore-story inkbunny: https://inkbunny.net/s/3010003 sofurry: https://www.sofurry.com/view/1992360 + sofurrybeta: https://sofurrybeta.com/s/V1YARWD1 tags: - oral vore - anthro predator diff --git a/src/content/stories/rose-s-binge.md b/src/content/stories/rose-s-binge.md index 7db3dcc..e4d907b 100644 --- a/src/content/stories/rose-s-binge.md +++ b/src/content/stories/rose-s-binge.md @@ -15,6 +15,7 @@ posts: furaffinity: https://www.furaffinity.net/view/57459926/ inkbunny: https://inkbunny.net/s/3377727 sofurry: https://www.sofurry.com/view/2156241 + sofurrybeta: https://sofurrybeta.com/s/ZmM3QrW1 weasyl: https://www.weasyl.com/~badmanners/submissions/2396279/c-rose-s-binge mastodon: https://meow.social/@BadManners/112827108738415986 tags: diff --git a/src/content/stories/ruffling-some-feathers.md b/src/content/stories/ruffling-some-feathers.md index 90968e4..388335c 100644 --- a/src/content/stories/ruffling-some-feathers.md +++ b/src/content/stories/ruffling-some-feathers.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245848/ruffling-some-feathers-vore-story inkbunny: https://inkbunny.net/s/3010004 sofurry: https://www.sofurry.com/view/1992363 + sofurrybeta: https://sofurrybeta.com/s/k1VYoGDn tags: - Muno - oral vore diff --git a/src/content/stories/spontaneous-sleepover.md b/src/content/stories/spontaneous-sleepover.md index ea9c5f1..c045913 100644 --- a/src/content/stories/spontaneous-sleepover.md +++ b/src/content/stories/spontaneous-sleepover.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245831/spontaneous-sleepover-vore-story inkbunny: https://inkbunny.net/s/3009991 sofurry: https://www.sofurry.com/view/1992340 + sofurrybeta: https://sofurrybeta.com/s/rm8DNdqm tags: - tail vore - anthro predator diff --git a/src/content/stories/taken-in.md b/src/content/stories/taken-in.md index c588196..8c5ea84 100644 --- a/src/content/stories/taken-in.md +++ b/src/content/stories/taken-in.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2345545/taken-in inkbunny: https://inkbunny.net/s/3231516 sofurry: https://www.sofurry.com/view/2096828 + sofurrybeta: https://sofurrybeta.com/s/B1QQYaz1 tags: - Sam Brendan - feral predator diff --git a/src/content/stories/tasting-high-consequences.md b/src/content/stories/tasting-high-consequences.md index 6c62828..e169d28 100644 --- a/src/content/stories/tasting-high-consequences.md +++ b/src/content/stories/tasting-high-consequences.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245857/tasting-high-consequences-vore-story inkbunny: https://inkbunny.net/s/3010016 sofurry: https://www.sofurry.com/view/1992377 + sofurrybeta: https://sofurrybeta.com/s/Oe5RNpMm tags: - oral vore - feral predator diff --git a/src/content/stories/team-building.md b/src/content/stories/team-building.md index 011f668..12c9a9d 100644 --- a/src/content/stories/team-building.md +++ b/src/content/stories/team-building.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2341116/c-team-building inkbunny: https://inkbunny.net/s/3219382 sofurry: https://www.sofurry.com/view/2091230 + sofurrybeta: https://sofurrybeta.com/s/RnoXYox1 tags: - cock vore - anal vore diff --git a/src/content/stories/team-effort.md b/src/content/stories/team-effort.md index a0b8747..3c11d9e 100644 --- a/src/content/stories/team-effort.md +++ b/src/content/stories/team-effort.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2291370/r-team-effort-vore-story inkbunny: https://inkbunny.net/s/3088444 sofurry: https://www.sofurry.com/view/2035089 + sofurrybeta: https://sofurrybeta.com/s/ynZ7L8w1 tags: - cock vore - anthro predator diff --git a/src/content/stories/the-last-livestream.md b/src/content/stories/the-last-livestream.md index 9998c86..62dd7a2 100644 --- a/src/content/stories/the-last-livestream.md +++ b/src/content/stories/the-last-livestream.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245824/the-last-livestream-vore-story inkbunny: https://inkbunny.net/s/3009975 sofurry: https://www.sofurry.com/view/1992325 + sofurrybeta: https://sofurrybeta.com/s/B1QQYK71 tags: - unbirth - anthro predator diff --git a/src/content/stories/the-lost-of-the-marshes/bonus-1-quince-s-fantasy.md b/src/content/stories/the-lost-of-the-marshes/bonus-1-quince-s-fantasy.md index 7a94dd6..6d7dece 100644 --- a/src/content/stories/the-lost-of-the-marshes/bonus-1-quince-s-fantasy.md +++ b/src/content/stories/the-lost-of-the-marshes/bonus-1-quince-s-fantasy.md @@ -17,6 +17,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245842/the-lost-of-the-marshes-bonus-quince-s-fantasy inkbunny: https://inkbunny.net/s/3009997 sofurry: https://www.sofurry.com/view/1992350 + sofurrybeta: https://sofurrybeta.com/s/k1VYoJGn tags: - oral vore - anthro predator diff --git a/src/content/stories/the-lost-of-the-marshes/chapter-1.md b/src/content/stories/the-lost-of-the-marshes/chapter-1.md index 660a607..64b1705 100644 --- a/src/content/stories/the-lost-of-the-marshes/chapter-1.md +++ b/src/content/stories/the-lost-of-the-marshes/chapter-1.md @@ -15,6 +15,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245800/the-lost-of-the-marshes-chapter-1-found inkbunny: https://inkbunny.net/s/3009918 sofurry: https://www.sofurry.com/view/1992256 + sofurrybeta: https://sofurrybeta.com/s/Rm0K4OKe tags: - oral vore - feral predator diff --git a/src/content/stories/the-lost-of-the-marshes/chapter-10.md b/src/content/stories/the-lost-of-the-marshes/chapter-10.md index 60325f1..086b422 100644 --- a/src/content/stories/the-lost-of-the-marshes/chapter-10.md +++ b/src/content/stories/the-lost-of-the-marshes/chapter-10.md @@ -17,6 +17,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245861/the-lost-of-the-marshes-chapter-10-memory inkbunny: https://inkbunny.net/s/3010039 sofurry: https://www.sofurry.com/view/1992381 + sofurrybeta: https://sofurrybeta.com/s/ve3QaApn tags: - oral vore - anal vore diff --git a/src/content/stories/the-lost-of-the-marshes/chapter-11.md b/src/content/stories/the-lost-of-the-marshes/chapter-11.md index 4a87c01..b5cdd71 100644 --- a/src/content/stories/the-lost-of-the-marshes/chapter-11.md +++ b/src/content/stories/the-lost-of-the-marshes/chapter-11.md @@ -15,6 +15,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2325367/the-lost-of-the-marshes-chapter-11-familiar inkbunny: https://inkbunny.net/s/3175040 sofurry: https://www.sofurry.com/view/2072674 + sofurrybeta: https://sofurrybeta.com/s/RnoXYo01 tags: - oral vore - cock vore diff --git a/src/content/stories/the-lost-of-the-marshes/chapter-2.md b/src/content/stories/the-lost-of-the-marshes/chapter-2.md index 8da97a6..9696b31 100644 --- a/src/content/stories/the-lost-of-the-marshes/chapter-2.md +++ b/src/content/stories/the-lost-of-the-marshes/chapter-2.md @@ -17,6 +17,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245802/the-lost-of-the-marshes-chapter-2-trust inkbunny: https://inkbunny.net/s/3009921 sofurry: https://www.sofurry.com/view/1992257 + sofurrybeta: https://sofurrybeta.com/s/dePdgr5e tags: - oral vore - feral predator diff --git a/src/content/stories/the-lost-of-the-marshes/chapter-3.md b/src/content/stories/the-lost-of-the-marshes/chapter-3.md index 8c3f2df..f33488b 100644 --- a/src/content/stories/the-lost-of-the-marshes/chapter-3.md +++ b/src/content/stories/the-lost-of-the-marshes/chapter-3.md @@ -17,6 +17,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245804/the-lost-of-the-marshes-chapter-3-home inkbunny: https://inkbunny.net/s/3009926 sofurry: https://www.sofurry.com/view/1992259 + sofurrybeta: https://sofurrybeta.com/s/q1xJz8Zm tags: - oral vore - macro predator diff --git a/src/content/stories/the-lost-of-the-marshes/chapter-4.md b/src/content/stories/the-lost-of-the-marshes/chapter-4.md index 7076b78..482bf57 100644 --- a/src/content/stories/the-lost-of-the-marshes/chapter-4.md +++ b/src/content/stories/the-lost-of-the-marshes/chapter-4.md @@ -19,6 +19,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245805/the-lost-of-the-marshes-chapter-4-change inkbunny: https://inkbunny.net/s/3009927 sofurry: https://www.sofurry.com/view/1992260 + sofurrybeta: https://sofurrybeta.com/s/ynd4LA7n tags: - oral vore - anthro predator diff --git a/src/content/stories/the-lost-of-the-marshes/chapter-5.md b/src/content/stories/the-lost-of-the-marshes/chapter-5.md index bc1bee8..2e75939 100644 --- a/src/content/stories/the-lost-of-the-marshes/chapter-5.md +++ b/src/content/stories/the-lost-of-the-marshes/chapter-5.md @@ -19,6 +19,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245811/the-lost-of-the-marshes-chapter-5-intersection inkbunny: https://inkbunny.net/s/3009933 sofurry: https://www.sofurry.com/view/1992297 + sofurrybeta: https://sofurrybeta.com/s/zeRb9Nge tags: - oral vore - anthro predator diff --git a/src/content/stories/the-lost-of-the-marshes/chapter-6.md b/src/content/stories/the-lost-of-the-marshes/chapter-6.md index 3df13df..2237ff2 100644 --- a/src/content/stories/the-lost-of-the-marshes/chapter-6.md +++ b/src/content/stories/the-lost-of-the-marshes/chapter-6.md @@ -17,6 +17,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245813/the-lost-of-the-marshes-chapter-6-pleasure inkbunny: https://inkbunny.net/s/3009938 sofurry: https://www.sofurry.com/view/1992302 + sofurrybeta: https://sofurrybeta.com/s/J1O5Zqgm tags: - oral vore - unbirth diff --git a/src/content/stories/the-lost-of-the-marshes/chapter-7.md b/src/content/stories/the-lost-of-the-marshes/chapter-7.md index 5c6bbdd..4845b5e 100644 --- a/src/content/stories/the-lost-of-the-marshes/chapter-7.md +++ b/src/content/stories/the-lost-of-the-marshes/chapter-7.md @@ -17,6 +17,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245817/the-lost-of-the-marshes-chapter-7-honesty inkbunny: https://inkbunny.net/s/3009943 sofurry: https://www.sofurry.com/view/1992307 + sofurrybeta: https://sofurrybeta.com/s/GnDLVbjn tags: - oral vore - anal vore diff --git a/src/content/stories/the-lost-of-the-marshes/chapter-8.md b/src/content/stories/the-lost-of-the-marshes/chapter-8.md index 128390f..5f1b9f9 100644 --- a/src/content/stories/the-lost-of-the-marshes/chapter-8.md +++ b/src/content/stories/the-lost-of-the-marshes/chapter-8.md @@ -15,6 +15,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245827/the-lost-of-the-marshes-chapter-8-estranged inkbunny: https://inkbunny.net/s/3009983 sofurry: https://www.sofurry.com/view/1992326 + sofurrybeta: https://sofurrybeta.com/s/rn92NpQ1 tags: - oral vore - anal vore diff --git a/src/content/stories/the-lost-of-the-marshes/chapter-9.md b/src/content/stories/the-lost-of-the-marshes/chapter-9.md index 9e8b18d..41bdc26 100644 --- a/src/content/stories/the-lost-of-the-marshes/chapter-9.md +++ b/src/content/stories/the-lost-of-the-marshes/chapter-9.md @@ -15,6 +15,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245844/the-lost-of-the-marshes-chapter-9-stuck inkbunny: https://inkbunny.net/s/3010000 sofurry: https://www.sofurry.com/view/1992354 + sofurrybeta: https://sofurrybeta.com/s/znJE5M7m tags: - oral vore - slit vore diff --git a/src/content/stories/tiny-accident.md b/src/content/stories/tiny-accident.md index cdc5c74..087ecab 100644 --- a/src/content/stories/tiny-accident.md +++ b/src/content/stories/tiny-accident.md @@ -15,6 +15,7 @@ posts: furaffinity: https://www.furaffinity.net/view/56026627/ inkbunny: https://inkbunny.net/s/3283508 sofurry: https://www.sofurry.com/view/2118138 + sofurrybeta: https://sofurrybeta.com/s/0mvwLB0n weasyl: https://www.weasyl.com/~badmanners/submissions/2363560/tiny-accident bluesky: https://bsky.app/profile/badmanners.xyz/post/3kok52wijz32c mastodon: https://meow.social/@BadManners/112157812554023271 diff --git a/src/content/stories/tomo-moku.md b/src/content/stories/tomo-moku.md index a95fc3d..4a0f471 100644 --- a/src/content/stories/tomo-moku.md +++ b/src/content/stories/tomo-moku.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245854/tomo-moku-lipu-pi-moku-musi inkbunny: https://inkbunny.net/s/3010010 sofurry: https://www.sofurry.com/view/1992374 + sofurrybeta: https://sofurrybeta.com/s/4nAMWvAn tags: - oral vore - ambiguous predator diff --git a/src/content/stories/trouble-sleeping.md b/src/content/stories/trouble-sleeping.md index 20662b9..d319d47 100644 --- a/src/content/stories/trouble-sleeping.md +++ b/src/content/stories/trouble-sleeping.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2305405/trouble-sleeping-vore-story inkbunny: https://inkbunny.net/s/3124166 sofurry: https://www.sofurry.com/view/2051787 + sofurrybeta: https://sofurrybeta.com/s/qmywZjQ1 tags: - unbirth - anthro predator diff --git a/src/content/stories/warped-friendship.md b/src/content/stories/warped-friendship.md index 4603d7d..3e9e992 100644 --- a/src/content/stories/warped-friendship.md +++ b/src/content/stories/warped-friendship.md @@ -16,6 +16,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2291371/r-warped-friendship-vore-story inkbunny: https://inkbunny.net/s/3088450 sofurry: https://www.sofurry.com/view/2035090 + sofurrybeta: https://sofurrybeta.com/s/AnKr5QPm tags: - oral vore - anthro predator diff --git a/src/content/stories/within-limits.md b/src/content/stories/within-limits.md index 75b17d1..63da3ff 100644 --- a/src/content/stories/within-limits.md +++ b/src/content/stories/within-limits.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2331157/c-within-limits inkbunny: https://inkbunny.net/s/3191950 sofurry: https://www.sofurry.com/view/2079346 + sofurrybeta: https://sofurrybeta.com/s/J1O5Z3km tags: - unbirth - cock vore diff --git a/src/content/stories/woofer-exploration.md b/src/content/stories/woofer-exploration.md index 7ae6766..16ce4a4 100644 --- a/src/content/stories/woofer-exploration.md +++ b/src/content/stories/woofer-exploration.md @@ -19,6 +19,7 @@ posts: furaffinity: https://www.furaffinity.net/view/57459921/ inkbunny: https://inkbunny.net/s/3377722 sofurry: https://www.sofurry.com/view/2156237 + sofurrybeta: https://sofurrybeta.com/s/rm8DBRWm weasyl: https://www.weasyl.com/~badmanners/submissions/2396278/woofer-exploration mastodon: https://meow.social/@BadManners/112827104119035982 tags: diff --git a/src/content/stories/you-re-home.md b/src/content/stories/you-re-home.md index c15de64..f06fd69 100644 --- a/src/content/stories/you-re-home.md +++ b/src/content/stories/you-re-home.md @@ -14,6 +14,7 @@ posts: weasyl: https://www.weasyl.com/~badmanners/submissions/2245815/you-re-home-vore-story inkbunny: https://inkbunny.net/s/3009942 sofurry: https://www.sofurry.com/view/1992304 + sofurrybeta: https://sofurrybeta.com/s/RnoXY6o1 tags: - oral vore - anthro predator diff --git a/src/content/tag-categories/6-vore-related-scenarios.yaml b/src/content/tag-categories/6-vore-related-scenarios.yaml index 793ce9b..65c80f4 100644 --- a/src/content/tag-categories/6-vore-related-scenarios.yaml +++ b/src/content/tag-categories/6-vore-related-scenarios.yaml @@ -65,5 +65,9 @@ tags: - cock vore - name: soul vore description: Scenarios where predators consume a soul instead of their prey's body. + - name: endo trait theft + description: Scenarios where predators acquire traits from their prey without digestion. + related: + - transformation - name: Vore Day description: Stories created in commemoration of Vore Day, which is celebrated on August 8th, and/or are set in said day. diff --git a/src/content/tag-categories/8-other-kinks.yaml b/src/content/tag-categories/8-other-kinks.yaml index 0da71f6..10b0efe 100644 --- a/src/content/tag-categories/8-other-kinks.yaml +++ b/src/content/tag-categories/8-other-kinks.yaml @@ -9,6 +9,8 @@ tags: - object vore - name: transformation description: Scenarios where a character changes body and/or species. + related: + - endo trait theft - name: netorare description: Scenarios involving a character cheating on their partner with or without consent, and/or cuckoldry. - name: sizeplay diff --git a/src/content/users/bad-manners.yaml b/src/content/users/bad-manners.yaml index 20f6f6d..03cfcfb 100644 --- a/src/content/users/bad-manners.yaml +++ b/src/content/users/bad-manners.yaml @@ -10,6 +10,7 @@ links: sofurry: link: https://bad-manners.sofurry.com/ username: Bad Manners + sofurrybeta: https://sofurrybeta.com/u/BadManners weasyl: https://www.weasyl.com/~BadManners twitter: https://twitter.com/BadManners__ mastodon: https://meow.social/@BadManners diff --git a/src/data/licenses.toml b/src/data/licenses.toml index fb5dc6a..650d8c9 100644 --- a/src/data/licenses.toml +++ b/src/data/licenses.toml @@ -51,6 +51,34 @@ author = "Noto Project Authors" source = "https://github.com/notofonts/latin-greek-cyrillic" license = { name = "SIL Open Font License v1.1", url = "https://opensource.org/license/ofl-1-1" } +[[attributions]] +author = "Simple Icons" +description = "Icons for third-party brands." +type = "icons" +source = "https://simpleicons.org" +license = { name = "CC0 1.0 Universal", url = "https://creativecommons.org/publicdomain/zero/1.0/" } +items = [ + "Weasyl", +] +notes = """All third-party copyrights and trademarks belong to their respective owners, \ +and I'm not affiliated with any of them.""" + +[[attributions]] +description = "Edited icons for other websites." +type = "icons" +author = { name = "Bad Manners", url = "https://badmanners.xyz", email = "me@badmanners.xyz>" } +source = "https://git.badmanners.xyz/badmanners/badmanners.xyz/src/branch/main/src/components/icons/brands" +license = { name = "CC0 1.0 Universal", url = "https://creativecommons.org/publicdomain/zero/1.0/" } +items = [ + "Eka's Portal", + "Fur Affinity", + "Inkbunny", + "SoFurry", +] +notes = """Original icons edited for personal use and released under a permissive license. +All third-party copyrights and trademarks belong to their respective owners, \ +and I'm not affiliated with any of them.""" + [[attributions]] author = "Font Awesome" description = "Generic icons." diff --git a/src/i18n/index.ts b/src/i18n/index.ts index 9456b57..9cd4e84 100644 --- a/src/i18n/index.ts +++ b/src/i18n/index.ts @@ -113,6 +113,30 @@ const UI_STRINGS = { en: "Click to reveal", tok: "Click to reveal summary in English", }, + "published_content/syndication_see_also_on": { + en: "See also on...", + tok: "o lukin lon ma ante", + }, + "published_content/syndication_eka": { + en: "Eka's Portal", + tok: "lipu Ikapoto", + }, + "published_content/syndication_furaffinity": { + en: "Fur Affinity", + tok: "lipu Panapinisi", + }, + "published_content/syndication_inkbunny": { + en: "Inkbunny", + tok: "lipu Inpani", + }, + "published_content/syndication_sofurry": { + en: "SoFurry", + tok: "lipu Sopanli", + }, + "published_content/syndication_weasyl": { + en: "Weasyl", + tok: "lipu Wise", + }, // Story page-specific strings "story/return_to_stories": { en: "Return to stories", diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro index 2cd6138..17d4707 100644 --- a/src/layouts/BaseLayout.astro +++ b/src/layouts/BaseLayout.astro @@ -7,9 +7,10 @@ import AgeRestrictedModal from "../components/AgeRestrictedModal.astro"; type Props = { pageTitle: string; lang?: string; + isAgeRestricted: boolean; }; -const { pageTitle, lang = "en" } = Astro.props; +const { pageTitle, lang = "en", isAgeRestricted } = Astro.props; --- <html lang={lang}> @@ -38,6 +39,6 @@ const { pageTitle, lang = "en" } = Astro.props; <body> <slot /> <DarkModeScript /> - <AgeRestrictedModal /> + {isAgeRestricted ? <AgeRestrictedModal /> : null} </body> </html> diff --git a/src/layouts/GalleryLayout.astro b/src/layouts/GalleryLayout.astro index ab1a9b2..28c0b79 100644 --- a/src/layouts/GalleryLayout.astro +++ b/src/layouts/GalleryLayout.astro @@ -17,18 +17,19 @@ import { type Props = { pageTitle: string; + isAgeRestricted?: boolean; enablePagefind?: boolean; class?: string; }; -const { pageTitle, enablePagefind, class: className } = Astro.props; +const { pageTitle, enablePagefind, class: className, isAgeRestricted } = Astro.props; const logo = await getImage({ src: logoBM, width: 192 }); const currentYear = new Date().getFullYear().toString(); const isCurrentRoute = (path: string) => Astro.url.pathname === path || (path !== "/" && Astro.url.pathname === `${path}/`); --- -<BaseLayout pageTitle={pageTitle}> +<BaseLayout pageTitle={pageTitle} isAgeRestricted={isAgeRestricted ?? true}> <Fragment slot="head"> <meta property="og:title" content={pageTitle || "Bad Manners"} /> <meta property="og:url" content={Astro.url} /> diff --git a/src/layouts/GameLayout.astro b/src/layouts/GameLayout.astro index e5c76b3..75a76af 100644 --- a/src/layouts/GameLayout.astro +++ b/src/layouts/GameLayout.astro @@ -22,6 +22,7 @@ const relatedGames = (await getEntries(props.relatedGames)).filter((game) => !ga title={props.title} lang={props.lang} isDraft={props.isDraft} + isAgeRestricted={props.isAgeRestricted} pubDate={props.pubDate} description={props.description} summary={undefined} diff --git a/src/layouts/PublishedContentLayout.astro b/src/layouts/PublishedContentLayout.astro index 3480126..4b1a109 100644 --- a/src/layouts/PublishedContentLayout.astro +++ b/src/layouts/PublishedContentLayout.astro @@ -20,6 +20,7 @@ import { IconChevronRight, IconArrowUp, } from "../components/icons"; +import ExternalPosts from "../components/ExternalPosts.astro"; interface RelatedContent { link: string; @@ -31,6 +32,7 @@ type Props = { title: string; lang: Lang; isDraft: boolean; + isAgeRestricted: boolean; pubDate?: Date; description: string; summary?: string; @@ -88,7 +90,7 @@ const returnTo = series : props.labelReturnTo.title; --- -<BaseLayout pageTitle={props.title} lang={props.lang}> +<BaseLayout pageTitle={props.title} lang={props.lang} isAgeRestricted={props.isAgeRestricted}> <Fragment slot="head"> {props.isDraft ? <meta name="robots" content="noindex" /> : null} <meta property="og:title" content={props.title} data-pagefind-meta="title[content]" /> @@ -153,11 +155,11 @@ const returnTo = series <a href={props.prev.link} rel="prev" - class="text-link flex items-center justify-center border-r border-stone-400 px-1 py-3 underline dark:border-stone-600" + class="h-entry u-url text-link flex items-center justify-center border-r border-stone-400 px-1 py-3 underline dark:border-stone-600" aria-label={props.labelPreviousContent} > <IconChevronLeft width="1.25rem" height="1.25rem" /> - <span class="ml-1">{props.prev.title}</span> + <span class="p-name ml-1">{props.prev.title}</span> </a> ) : ( <div class="h-full border-r border-stone-400 dark:border-stone-600" aria-hidden="true" /> @@ -166,10 +168,10 @@ const returnTo = series <a href={props.next.link} rel="next" - class="text-link flex items-center justify-center px-1 py-3 underline" + class="h-entry u-url text-link flex items-center justify-center px-1 py-3 underline" aria-label={props.labelNextContent} > - <span class="mr-1">{props.next.title}</span> + <span class="p-name mr-1">{props.next.title}</span> <IconChevronRight width="1.25rem" height="1.25rem" /> </a> ) : ( @@ -376,6 +378,7 @@ const returnTo = series </section> ) : null } + <ExternalPosts lang={props.lang} posts={props.posts} /> {props.posts.mastodon ? <MastodonComments lang={props.lang} {...props.posts.mastodon} /> : null} </main> <div diff --git a/src/layouts/StoryLayout.astro b/src/layouts/StoryLayout.astro index 9477911..33e199d 100644 --- a/src/layouts/StoryLayout.astro +++ b/src/layouts/StoryLayout.astro @@ -27,6 +27,7 @@ const wordCount = props.wordCount?.toString(); title={props.title} lang={props.lang} isDraft={props.isDraft} + isAgeRestricted={props.isAgeRestricted} pubDate={props.pubDate} description={props.description} summary={props.summary} diff --git a/src/pages/index.astro b/src/pages/index.astro index b3733c6..ebcb7a5 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -79,8 +79,7 @@ const latestItems: LatestItemsEntry[] = await Promise.all( <hr class="mb-3 ml-[2px] mt-2 h-[4px] max-w-xs rounded-sm bg-stone-800 dark:bg-stone-100" /> <div class="p-summary"> <p class="my-4"> - Glad to see you here. You can expect lots of safe vore/endosoma ahead. Use the navigation menu to navigate through - my content. + Hey there, welcome to my corner of the Internet! You can expect lots of safe vore/endosoma ahead. </p> <ul class="list-disc pl-8"> <li><a class="text-link underline" href="/stories/1">Read my stories!</a></li> diff --git a/src/utils/get_website_link_for_user.ts b/src/utils/get_website_link_for_user.ts index 0de0c4f..9ee867b 100644 --- a/src/utils/get_website_link_for_user.ts +++ b/src/utils/get_website_link_for_user.ts @@ -80,6 +80,13 @@ export function getWebsiteLinkForUser( return `ib!${getUserDataForWebsite(user, "inkbunny").username}`; } break; + case "sofurrybeta": + if ("sofurrybeta" in links) { + return `@${links.sofurrybeta!.username}`; + } else if ("sofurry" in links) { + return `[${links.sofurry!.username}](${links.sofurry!.link})`; + } + break; case "twitter": if ("twitter" in links) { return `@${getUserDataForWebsite(user, "twitter").username}`; diff --git a/src/utils/qualify_local_urls_in_markdown.ts b/src/utils/qualify_local_urls_in_markdown.ts index 002bb08..94004ae 100644 --- a/src/utils/qualify_local_urls_in_markdown.ts +++ b/src/utils/qualify_local_urls_in_markdown.ts @@ -1,5 +1,5 @@ import { getCollection, getEntry } from "astro:content"; -import type { Lang, PostWebsite } from "../content/config"; +import type { Lang, PostWebsite, UserWebsite } from "../content/config"; import { getWebsiteLinkForUser } from "./get_website_link_for_user"; import { getUsernameForLang } from "./get_username_for_lang"; @@ -56,8 +56,8 @@ export async function qualifyLocalURLsInMarkdown(originalText: string, lang: Lan if (!story) { throw new Error(`Couldn't find story with slug "${slug}"`); } - if (typeof website === "string" && story.data.posts[website]?.link) { - replacements.push(`[${text}](${story.data.posts[website].link})`); + if (typeof website === "string" && story.data.posts[website as PostWebsite]?.link) { + replacements.push(`[${text}](${story.data.posts[website as PostWebsite]!.link})`); continue; } break; @@ -66,8 +66,8 @@ export async function qualifyLocalURLsInMarkdown(originalText: string, lang: Lan if (!game) { throw new Error(`Couldn't find game with slug "${slug}"`); } - if (typeof website === "string" && game.data.posts[website]?.link) { - replacements.push(`[${text}](${game.data.posts[website].link})`); + if (typeof website === "string" && game.data.posts[website as PostWebsite]?.link) { + replacements.push(`[${text}](${game.data.posts[website as PostWebsite]!.link})`); continue; } break; @@ -78,8 +78,8 @@ export async function qualifyLocalURLsInMarkdown(originalText: string, lang: Lan } // If there's a label in the link, use that if possible if (text) { - if (typeof website === "string" && user.data.links[website]?.link) { - replacements.push(`[${text}](${user.data.links[website].link})`); + if (typeof website === "string" && user.data.links[website as UserWebsite]?.link) { + replacements.push(`[${text}](${user.data.links[website as UserWebsite]!.link})`); continue; } else if (user.data.preferredLink) { replacements.push(`[${text}](${user.data.links[user.data.preferredLink]!.link})`); @@ -87,7 +87,9 @@ export async function qualifyLocalURLsInMarkdown(originalText: string, lang: Lan } } // Otherwise (i.e. label is empty), use the username for the website - replacements.push(getWebsiteLinkForUser(user, website, (user) => getUsernameForLang(user, lang))); + replacements.push( + getWebsiteLinkForUser(user, website as UserWebsite, (user) => getUsernameForLang(user, lang)), + ); continue; default: const unknown: never = contentPrefix;