feat: 添加 Gitea 仓库卡片组件支持

This commit is contained in:
2026-03-30 13:30:27 +08:00
parent 6243898db3
commit 1364698b81
4 changed files with 120 additions and 13 deletions

View File

@@ -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"),

View File

@@ -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)

View File

@@ -0,0 +1,95 @@
/// <reference types="mdast" />
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,
],
);
}

View File

@@ -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