diff --git a/astro.config.mjs b/astro.config.mjs index c64574c..907463e 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -4,9 +4,9 @@ import tailwind from "@astrojs/tailwind"; import { pluginCollapsibleSections } from "@expressive-code/plugin-collapsible-sections"; import { pluginLineNumbers } from "@expressive-code/plugin-line-numbers"; import swup from "@swup/astro"; +import { defineConfig } from "astro/config"; import expressiveCode from "astro-expressive-code"; import icon from "astro-icon"; -import { defineConfig } from "astro/config"; import rehypeAutolinkHeadings from "rehype-autolink-headings"; import rehypeComponents from "rehype-components"; /* Render the custom directive content */ import rehypeKatex from "rehype-katex"; @@ -16,14 +16,15 @@ import remarkGithubAdmonitionsToDirectives from "remark-github-admonitions-to-di import remarkMath from "remark-math"; import remarkSectionize from "remark-sectionize"; import { expressiveCodeConfig } from "./src/config.ts"; +import { pluginCustomCopyButton } from "./src/plugins/expressive-code/custom-copy-button.js"; import { pluginLanguageBadge } from "./src/plugins/expressive-code/language-badge.ts"; import { AdmonitionComponent } from "./src/plugins/rehype-component-admonition.mjs"; +import { GiteaCardComponent } from "./src/plugins/rehype-component-gitea-card.mjs"; import { GithubCardComponent } from "./src/plugins/rehype-component-github-card.mjs"; import { GitlabCardComponent } from "./src/plugins/rehype-component-gitlab-card.mjs"; import { parseDirectiveNode } from "./src/plugins/remark-directive-rehype.js"; import { remarkExcerpt } from "./src/plugins/remark-excerpt.js"; import { remarkReadingTime } from "./src/plugins/remark-reading-time.mjs"; -import { pluginCustomCopyButton } from "./src/plugins/expressive-code/custom-copy-button.js"; // https://astro.build/config export default defineConfig({ @@ -62,12 +63,12 @@ export default defineConfig({ pluginCollapsibleSections(), pluginLineNumbers(), pluginLanguageBadge(), - pluginCustomCopyButton() + pluginCustomCopyButton(), ], defaultProps: { wrap: true, overridesByLang: { - 'shellsession': { + shellsession: { showLineNumbers: false, }, }, @@ -77,7 +78,8 @@ export default defineConfig({ borderRadius: "0.75rem", borderColor: "none", codeFontSize: "0.875rem", - codeFontFamily: "'JetBrains Mono Variable', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace", + codeFontFamily: + "'JetBrains Mono Variable', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace", codeLineHeight: "1.5rem", frames: { editorBackground: "var(--codeblock-bg)", @@ -88,19 +90,19 @@ export default defineConfig({ editorActiveTabIndicatorBottomColor: "var(--primary)", editorActiveTabIndicatorTopColor: "none", editorTabBarBorderBottomColor: "var(--codeblock-topbar-bg)", - terminalTitlebarBorderBottomColor: "none" + terminalTitlebarBorderBottomColor: "none", }, textMarkers: { delHue: 0, insHue: 180, - markHue: 250 - } + markHue: 250, + }, }, frames: { showCopyToClipboardButton: false, - } + }, }), - svelte(), + svelte(), sitemap(), ], markdown: { @@ -122,6 +124,7 @@ export default defineConfig({ components: { github: GithubCardComponent, gitlab: GitlabCardComponent, + gitea: GiteaCardComponent, note: (x, y) => AdmonitionComponent(x, y, "note"), tip: (x, y) => AdmonitionComponent(x, y, "tip"), important: (x, y) => AdmonitionComponent(x, y, "important"), diff --git a/src/content/spec/about.md b/src/content/spec/about.md index c5c6807..b0cfd0a 100644 --- a/src/content/spec/about.md +++ b/src/content/spec/about.md @@ -3,7 +3,8 @@ This is the demo site for [Fuwari](https://github.com/saicaca/fuwari). ::github{repo="saicaca/fuwari"} -::gitlab{repo="CapaCake/milkblogs-fuwari" service="https://git.milkfunc.top"} +::gitea{repo="CapaCake/milkblogs-fuwari" service="https://git.milkfunc.top"} + > ### Sources of images used in this site > - [Unsplash](https://unsplash.com/) > - [星と少女](https://www.pixiv.net/artworks/108916539) by [Stella](https://www.pixiv.net/users/93273965) diff --git a/src/plugins/rehype-component-gitea-card.mjs b/src/plugins/rehype-component-gitea-card.mjs new file mode 100644 index 0000000..4a12c33 --- /dev/null +++ b/src/plugins/rehype-component-gitea-card.mjs @@ -0,0 +1,95 @@ +/// +import { h } from "hastscript"; + +/** + * Creates a Gitea Card component. + * + * @param {Object} properties - The properties of the component. + * @param {string} properties.repo - The Gitea repository in the format "owner/repo". + * @param {string} properties.service - (optional) Third-Party Gitea service provider. + * @param {import('mdast').RootContent[]} children - The children elements of the component. + * @returns {import('mdast').Parent} The created Gitea Card component. + */ +export function GiteaCardComponent(properties, children) { + if (Array.isArray(children) && children.length !== 0) + return h("div", { class: "hidden" }, [ + 'Invalid directive. ("gitea" directive must be leaf type "::gitea{repo="owner/repo"}")', + ]); + + if (!properties.repo || !properties.repo.includes("/")) + return h( + "div", + { class: "hidden" }, + 'Invalid repository. ("repo" attributte must be in the format "owner/repo")', + ); + + const repo = properties.repo; + const service = properties?.service || "https://gitea.com"; + const cardUuid = `GC${Math.random().toString(36).slice(-6)}`; + + const nAvatar = h(`div#${cardUuid}-avatar`, { class: "gc-avatar" }); + const nLanguage = h( + `span#${cardUuid}-language`, + { class: "gc-language" }, + "Waiting...", + ); + + const nTitle = h("div", { class: "gc-titlebar" }, [ + h("div", { class: "gc-titlebar-left" }, [ + h("div", { class: "gc-owner" }, [ + nAvatar, + h("div", { class: "gc-user" }, repo.split("/")[0]), + ]), + h("div", { class: "gc-divider" }, "/"), + h("div", { class: "gc-repo" }, repo.split("/")[1]), + ]), + h("div", { class: "gitea-logo" }), + ]); + + const nDescription = h( + `div#${cardUuid}-description`, + { class: "gc-description" }, + "Waiting for Gitea API...", + ); + + const nStars = h(`div#${cardUuid}-stars`, { class: "gc-stars" }, "00K"); + const nForks = h(`div#${cardUuid}-forks`, { class: "gc-forks" }, "0K"); + + const nScript = h( + `script#${cardUuid}-script`, + { type: "text/javascript", defer: true }, + ` + fetch('${service}/api/v1/repos/${repo}', { referrerPolicy: "no-referrer" }).then(response => response.json()).then(data => { + document.getElementById('${cardUuid}-description').innerText = data.description?.replace(/:[a-zA-Z0-9_]+:/g, '') || "Description not set"; + document.getElementById('${cardUuid}-language').innerText = data.language; + document.getElementById('${cardUuid}-forks').innerText = Intl.NumberFormat('en-us', { notation: "compact", maximumFractionDigits: 1 }).format(data.forks_count).replaceAll("\\u202f", ''); + document.getElementById('${cardUuid}-stars').innerText = Intl.NumberFormat('en-us', { notation: "compact", maximumFractionDigits: 1 }).format(data.stars_count).replaceAll("\\u202f", ''); + const avatarEl = document.getElementById('${cardUuid}-avatar'); + avatarEl.style.backgroundImage = 'url(' + data.owner.avatar_url + ')'; + avatarEl.style.backgroundColor = 'transparent'; + document.getElementById('${cardUuid}-card').classList.remove("fetch-waiting"); + console.log("[GITEA-CARD] Loaded card for ${repo} | ${cardUuid}.") + }).catch(err => { + const c = document.getElementById('${cardUuid}-card'); + c?.classList.add("fetch-error"); + console.warn("[GITEA-CARD] (Error) Loading card for ${repo} | ${cardUuid}.") + }) + `, + ); + + return h( + `a#${cardUuid}-card`, + { + class: "card-github fetch-waiting no-styling", + href: `${service}/${repo}`, + target: "_blank", + repo, + }, + [ + nTitle, + nDescription, + h("div", { class: "gc-infobar" }, [nStars, nForks, nLanguage]), + nScript, + ], + ); +} diff --git a/src/styles/markdown-extend.styl b/src/styles/markdown-extend.styl index ed334d6..0f280c8 100644 --- a/src/styles/markdown-extend.styl +++ b/src/styles/markdown-extend.styl @@ -163,7 +163,7 @@ a.card-github .gc-language display: none - .gc-stars, .gc-forks, .gc-license, .github-logo, .gitlab-logo + .gc-stars, .gc-forks, .gc-license, .github-logo, .gitlab-logo, .gitea-logo font-weight: 500 font-size: 0.875rem opacity: 0.9; @@ -214,6 +214,14 @@ a.card-github margin-right: 0 mask-image: url("https://images.ctfassets.net/xz1dnu24egyd/4V92fFTJOIlTPHHzSdfxem/3fdc9f0d82f08ed4c355c6e4126b870c/gitlab-logo-600.svg") + .gitea-logo + font-size: 1.25rem + + &:before + background-color: var(--tw-prose-headings) + margin-right: 0 + mask-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 640 640%22%3E%3Cpath fill=%22%23609926%22 d=%22M622.7 149.8c-4.1-4.1-9.6-4-9.6-4s-117.2 6.6-177.9 8c-13.3 0.3-26.5 0.6-39.6 0.7c0 39.1 0 78.2 0 117.2c-5.5-2.6-11.1-5.3-16.6-7.9c0-36.4-0.1-109.2-0.1-109.2c-29 0.4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5c-9.8-0.6-22.5-2.1-39 1.5c-8.7 1.8-33.5 7.4-53.8 26.9C-4.9 212.4 6.6 276.2 8 285.8c1.7 11.7 6.9 44.2 31.7 72.5c45.8 56.1 144.4 54.8 144.4 54.8s12.1 28.9 30.6 55.5c25 33.1 50.7 58.9 75.7 62c63 0 188.9-0.1 188.9-0.1s12 0.1 28.3-10.3c14-8.5 26.5-23.4 26.5-23.4s12.9-13.8 30.9-45.3c5.5-9.7 10.1-19.1 14.1-28c0 0 55.2-117.1 55.2-231.1C633.2 157.9 624.7 151.8 622.7 149.8z M125.6 353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6 321.8 60 295.4c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5 38.5-30c13.8-3.7 31-3.1 31-3.1s7.1 59.4 15.7 94.2c7.2 29.2 24.8 77.7 24.8 77.7S142.5 359.9 125.6 353.9z M425.9 461.5c0 0-6.1 14.5-19.6 15.4c-5.8 0.4-10.3-1.2-10.3-1.2s-0.3-0.1-5.3-2.1l-112.9-55c0 0-10.9-5.7-12.8-15.6c-2.2-8.1 2.7-18.1 2.7-18.1L322 273c0 0 4.8-9.7 12.2-13c0.6-0.3 2.3-1 4.5-1.5c8.1-2.1 18 2.8 18 2.8l110.7 53.7c0 0 12.6 5.7 15.3 16.2c1.9 7.4-0.5 14-1.8 17.2C474.6 363.8 425.9 461.5 425.9 461.5z%22/%3E%3Cpath fill=%22%23609926%22 d=%22M326.8 380.1c-8.2 0.1-15.4 5.8-17.3 13.8c-1.9 8 2 16.3 9.1 20c7.7 4 17.5 1.8 22.7-5.4c5.1-7.1 4.3-16.9-1.8-23.1l24-49.1c1.5 0.1 3.7 0.2 6.2-0.5c4.1-0.9 7.1-3.6 7.1-3.6c4.2 1.8 8.6 3.8 13.2 6.1c4.8 2.4 9.3 4.9 13.4 7.3c0.9 0.5 1.8 1.1 2.8 1.9c1.6 1.3 3.4 3.1 4.7 5.5c1.9 5.5-1.9 14.9-1.9 14.9c-2.3 7.6-18.4 40.6-18.4 40.6c-8.1-0.2-15.3 5-17.7 12.5c-2.6 8.1 1.1 17.3 8.9 21.3c7.8 4 17.4 1.7 22.5-5.3c5-6.8 4.6-16.3-1.1-22.6c1.9-3.7 3.7-7.4 5.6-11.3c5-10.4 13.5-30.4 13.5-30.4c0.9-1.7 5.7-10.3 2.7-21.3c-2.5-11.4-12.6-16.7-12.6-16.7c-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3c4.7-9.7 9.4-19.3 14.1-29c-4.1-2-8.1-4-12.2-6.1c-4.8 9.8-9.7 19.7-14.5 29.5c-6.7-0.1-12.9 3.5-16.1 9.4c-3.4 6.3-2.7 14.1 1.9 19.8C343.2 346.5 335 363.3 326.8 380.1z%22/%3E%3C/svg%3E") + a.card-github.fetch-waiting pointer-events: none opacity: 0.7 @@ -247,7 +255,7 @@ a.card-github.fetch-error 100% opacity: 0.15 -.card-github, .gc-description, .gc-titlebar, .gc-stars, .gc-forks, .gc-license, .gc-avatar, .github-logo, .gitlab-logo +.card-github, .gc-description, .gc-titlebar, .gc-stars, .gc-forks, .gc-license, .gc-avatar, .github-logo, .gitlab-logo, .gitea-logo transition-property: all transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1) transition-duration: 0.15s