diff --git a/README.md b/README.md index 82e84db..10696c1 100644 --- a/README.md +++ b/README.md @@ -21,16 +21,25 @@ npm install ```bash npm run dev # Start development server (quit with Ctrl-C) +npm run sync # Rebuild types from Astro config npm run prettier # Prettier formatting ``` +### Configuration + +The following optional environment variables can be set with `.env`: + +| Name | Type | Description | +|-|-|-| +| `APACHE_CONFIG` | boolean | Whether to generate an `.htaccess` Apache config file at the root of the output directory or not. | + ### Build and deploy to remote ```bash npm run build ``` -Then, if using rsync, after configuring the `websitebm` host (or the name of your choosing) in `~/.ssh/config`, you can use a command like: +Then, if you're using rsync, after configuring the `websitebm` host (or the name of your choosing) in `~/.ssh/config`, you can use a command like: ```bash rsync --delete-after -acP dist/ websitebm:/home/public diff --git a/astro.config.mjs b/astro.config.mjs index c949596..9a3d231 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,4 +1,4 @@ -import { defineConfig } from "astro/config"; +import { defineConfig, envField } from "astro/config"; import tailwindIntegration from "@astrojs/tailwind"; // https://astro.build/config @@ -16,4 +16,11 @@ export default defineConfig({ redirects: { "/tos": "/terms_of_service", }, + experimental: { + env: { + schema: { + APACHE_CONFIG: envField.boolean({ context: "server", access: "public", default: false }), + }, + }, + }, }); diff --git a/package-lock.json b/package-lock.json index e4b6096..917a400 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,13 @@ { "name": "badmanners.xyz", - "version": "2.0.1", + "version": "2.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "badmanners.xyz", - "version": "2.0.1", + "version": "2.0.2", + "hasInstallScript": true, "dependencies": { "@astrojs/check": "^0.9.2", "@astrojs/rss": "^4.0.7", diff --git a/package.json b/package.json index 2433866..cc8cf84 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,9 @@ { "name": "badmanners.xyz", "type": "module", - "version": "2.0.1", + "version": "2.0.2", "scripts": { + "postinstall": "astro sync", "dev": "astro dev", "start": "astro dev", "build": "astro check && astro build", diff --git a/public/licenses.txt b/public/licenses.txt index af2fbf7..1fcc55f 100644 --- a/public/licenses.txt +++ b/public/licenses.txt @@ -4,9 +4,9 @@ All attributed artwork is copyrighted by their respective creators and distribut The Jost* typeface is copyrighted by indestructible type* and is distributed under the SIL Open Font License v1.1: https://opensource.org/license/ofl-1-1 -The SVG icons for Bluesky, Codeberg, Discord, Itch.io, Keybase, GitHub, GitLab, Mastodon, Signal, Steam, Telegram, Weasyl, and X were created for the Simple Icons project and are distributed under the Creative Commons Zero v1.0 Universal license: https://creativecommons.org/publicdomain/zero/1.0/ +The SVG icons for Bluesky, Codeberg, Discord, Itch.io, Keybase, GitHub, GitLab, Mastodon, Picarto, Signal, Steam, Telegram, Twitch, Weasyl, and X were created for the Simple Icons project and are distributed under the Creative Commons Zero v1.0 Universal license: https://creativecommons.org/publicdomain/zero/1.0/ -The SVG icons for Eka's Portal, Fur Affinity, Inkbunny, SoFurry, and SubscribeStar were created by me for personal use, and are distributed under the Creative Commons Zero v1.0 Universal license: https://creativecommons.org/publicdomain/zero/1.0/ +The SVG icons for Eka's Portal, Fur Affinity, Inkbunny, Itaku, Neocities, SoFurry, and SubscribeStar were created by me from their respective logos. They are available for free use under the Creative Commons Zero v1.0 Universal license: https://creativecommons.org/publicdomain/zero/1.0/ The generic SVG icons were created by Font Awesome and are distributed under CC-BY-4.0: https://creativecommons.org/licenses/by/4.0/ diff --git a/scripts/deploy-lftp.ts b/scripts/deploy-lftp.ts index d418de3..fb41ffa 100644 --- a/scripts/deploy-lftp.ts +++ b/scripts/deploy-lftp.ts @@ -1,4 +1,5 @@ import { spawn } from "node:child_process"; +import { join } from "node:path"; import { program, Option } from "commander"; interface DeployLftpOptions { @@ -7,17 +8,18 @@ interface DeployLftpOptions { password: string; targetFolder: string; sourceFolder: string; + assetsFolder: string; } -async function deployLftp({ host, user, password, targetFolder, sourceFolder }: DeployLftpOptions) { +async function deployLftp({ host, user, password, targetFolder, sourceFolder, assetsFolder }: DeployLftpOptions) { const process = spawn( "lftp", [ "-c", [ `open -u ${user},${password} ${host}`, - `mirror --reverse --include-glob assets/* --delete --only-missing --no-perms --verbose ${sourceFolder} ${targetFolder}`, - `mirror --reverse --exclude-glob assets/* --delete --no-perms --verbose ${sourceFolder} ${targetFolder}`, + `mirror --reverse --include-glob ${join(assetsFolder, "*")} --delete --only-missing --no-perms --verbose ${sourceFolder} ${targetFolder}`, + `mirror --reverse --exclude-glob ${join(assetsFolder, "*")} --delete --no-perms --verbose ${sourceFolder} ${targetFolder}`, `bye`, ].join("\n"), ], @@ -58,5 +60,10 @@ await program .env("DEPLOY_LFTP_SOURCEFOLDER") .default("dist/"), ) + .addOption( + new Option("-a, --assets-folder ", "Directory inside of --source-folder of assets with hash-based names") + .env("DEPLOY_LFTP_ASSETSFOLDER") + .default("assets/"), + ) .action(deployLftp) .parseAsync(); diff --git a/src/components/icons/IconEllipsis.astro b/src/components/icons/IconEllipsis.astro new file mode 100644 index 0000000..396ecec --- /dev/null +++ b/src/components/icons/IconEllipsis.astro @@ -0,0 +1,13 @@ +--- +import SVGIcon from "./SVGIcon.astro"; + +type Props = { + width: string; + height: string; + class?: string; +}; +--- + + + + diff --git a/src/components/icons/brands/IconItaku.astro b/src/components/icons/brands/IconItaku.astro new file mode 100644 index 0000000..cc02fcd --- /dev/null +++ b/src/components/icons/brands/IconItaku.astro @@ -0,0 +1,15 @@ +--- +import SVGIcon from "../SVGIcon.astro"; + +type Props = { + width: string; + height: string; + class?: string; +}; +--- + + + + diff --git a/src/components/icons/brands/IconNeocities.astro b/src/components/icons/brands/IconNeocities.astro new file mode 100644 index 0000000..a8fd83f --- /dev/null +++ b/src/components/icons/brands/IconNeocities.astro @@ -0,0 +1,14 @@ +--- +import SVGIcon from "../SVGIcon.astro"; + +type Props = { + width: string; + height: string; + class?: string; +}; +--- + + + + diff --git a/src/components/icons/brands/IconPicarto.astro b/src/components/icons/brands/IconPicarto.astro new file mode 100644 index 0000000..5691193 --- /dev/null +++ b/src/components/icons/brands/IconPicarto.astro @@ -0,0 +1,13 @@ +--- +import SVGIcon from "../SVGIcon.astro"; + +type Props = { + width: string; + height: string; + class?: string; +}; +--- + + + + diff --git a/src/components/icons/brands/IconTwitch.astro b/src/components/icons/brands/IconTwitch.astro new file mode 100644 index 0000000..b4b0cad --- /dev/null +++ b/src/components/icons/brands/IconTwitch.astro @@ -0,0 +1,13 @@ +--- +import SVGIcon from "../SVGIcon.astro"; + +type Props = { + width: string; + height: string; + class?: string; +}; +--- + + + + diff --git a/src/env.d.ts b/src/env.d.ts index acef35f..338ba9e 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -1,2 +1,3 @@ +/// /// /// diff --git a/src/pages/[...config].ts b/src/pages/[...config].ts new file mode 100644 index 0000000..f64c99c --- /dev/null +++ b/src/pages/[...config].ts @@ -0,0 +1,46 @@ +import type { APIRoute, GetStaticPaths } from "astro"; +import { APACHE_CONFIG } from "astro:env/server"; + +const htaccess = ` +ErrorDocument 404 /404.html +RedirectMatch 301 ^/tos(\/(index.html)?)?$ /terms_of_service/ +Redirect 301 /@/aryion https://aryion.com/g4/user/BadManners +Redirect 301 /@/eka https://aryion.com/g4/user/BadManners +Redirect 301 /@/bluesky https://bsky.app/profile/badmanners.xyz +Redirect 301 /@/bsky https://bsky.app/profile/badmanners.xyz +Redirect 301 /@/codeberg https://codeberg.org/BadManners +Redirect 301 /@/fa https://www.furaffinity.net/user/badmanners +Redirect 301 /@/furaffinity https://www.furaffinity.net/user/badmanners +Redirect 301 /@/gallery https://gallery.badmanners.xyz +Redirect 301 /@/github https://github.com/BadMannersXYZ +Redirect 301 /@/gitlab https://gitlab.com/Bad_Manners +Redirect 301 /@/inkbunny https://inkbunny.net/BadManners +Redirect 301 /@/ib https://inkbunny.net/BadManners +Redirect 301 /@/itaku https://itaku.ee/profile/badmanners +Redirect 301 /@/itch https://bad-manners.itch.io +Redirect 301 /@/keybase https://keybase.io/badmanners +Redirect 301 /@/mastodon https://meow.social/@BadManners +Redirect 301 /@/meow.social https://meow.social/@BadManners +Redirect 301 /@/neocities https://badmanners.neocities.org/ +Redirect 301 /@/picarto https://www.picarto.tv/BadManners +Redirect 301 /@/signal https://signal.me/#eu/ytt_rk0fFmAB2JAW-x2PbUiJyc_H3kYmfL_Pq4QNh5QIDsiFtjdFHaqFRs1D36tB +Redirect 301 /@/sf https://bad-manners.sofurry.com/ +Redirect 301 /@/sofurry https://bad-manners.sofurry.com/ +Redirect 301 /@/steam https://steamcommunity.com/id/badmanners_/ +Redirect 301 /@/subscribestar https://subscribestar.adult/bad-manners +Redirect 301 /@/telegram https://t.me/bad_manners +Redirect 301 /@/t.me https://t.me/bad_manners +Redirect 301 /@/twitch https://www.twitch.tv/bad__manners +Redirect 301 /@/weasyl https://www.weasyl.com/~badmanners +Redirect 301 /@/x https://x.com/BadManners__ +Redirect 301 /@/twitter https://x.com/BadManners__ +`.trim(); + +export const getStaticPaths: GetStaticPaths = async () => { + if (APACHE_CONFIG) { + return [{ params: { config: ".htaccess" }, props: { body: htaccess } }]; + } + return []; +}; + +export const GET: APIRoute = ({ props: { body } }) => new Response(body); diff --git a/src/pages/contact.astro b/src/pages/contact.astro index e0e71c9..dec943b 100644 --- a/src/pages/contact.astro +++ b/src/pages/contact.astro @@ -16,7 +16,7 @@ import IconTelegram from "../components/icons/brands/IconTelegram.astro";

Contact

- Feel free to reach out to me through any of my socials below, or by + Feel free to reach out through my main socials below, or by messaging me on any of my galleries, if you wanna talk about anything! diff --git a/src/pages/index.astro b/src/pages/index.astro index 8fca85d..e041d5d 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -10,13 +10,18 @@ import IconInkbunny from "../components/icons/brands/IconInkbunny.astro"; import IconItchIO from "../components/icons/brands/IconItchIO.astro"; import IconKeybase from "../components/icons/brands/IconKeybase.astro"; import IconMastodon from "../components/icons/brands/IconMastodon.astro"; +import IconNeocities from "../components/icons/brands/IconNeocities.astro"; +import IconPicarto from "../components/icons/brands/IconPicarto.astro"; import IconSignal from "../components/icons/brands/IconSignal.astro"; import IconSoFurry from "../components/icons/brands/IconSoFurry.astro"; import IconSteam from "../components/icons/brands/IconSteam.astro"; import IconSubscribeStar from "../components/icons/brands/IconSubscribeStar.astro"; import IconTelegram from "../components/icons/brands/IconTelegram.astro"; +import IconTwitch from "../components/icons/brands/IconTwitch.astro"; import IconWeasyl from "../components/icons/brands/IconWeasyl.astro"; import IconX from "../components/icons/brands/IconX.astro"; +import IconEllipsis from "../components/icons/IconEllipsis.astro"; +import IconItaku from "../components/icons/brands/IconItaku.astro"; --- @@ -37,229 +42,282 @@ import IconX from "../components/icons/brands/IconX.astro"; class="u-logo mx-auto my-4 h-screen max-h-48 rounded-full transition-transform hover:scale-110 motion-reduce:transition-none motion-reduce:hover:scale-100 sm:max-h-72" />

I'm a safe vore enthusiast, and a furry who occasionally writes stuff.

-
+ + + diff --git a/src/pages/sam_brendan.astro b/src/pages/sam_brendan.astro index cc4a82e..ed57191 100644 --- a/src/pages/sam_brendan.astro +++ b/src/pages/sam_brendan.astro @@ -38,7 +38,7 @@ import ImageSamRefsheet from "../assets/images/sam_refsheet.webp"; Rimmi . Click to view in higher quality. + >. Click to view a high quality version.

@@ -86,7 +86,7 @@ import ImageSamRefsheet from "../assets/images/sam_refsheet.webp"; OliveCow . Click to view in higher quality. + >. Click to view a high quality version.