From adc8663c367a7fffb885f603f2e075aaf9895dd1 Mon Sep 17 00:00:00 2001
From: thinkasany <480968828@qq.com>
Date: Fri, 12 Apr 2024 17:59:41 +0800
Subject: [PATCH] feat: ContributorsList
---
.dumi/theme/layouts/GlobalLayout.tsx | 25 ++++++-
.../theme/slots/Content/ContributorAvatar.tsx | 44 +++++++++++++
.dumi/theme/slots/Content/Contributors.tsx | 65 +++++++++++++++++++
package.json | 3 +-
pnpm-lock.yaml | 11 ++++
5 files changed, 146 insertions(+), 2 deletions(-)
create mode 100644 .dumi/theme/slots/Content/ContributorAvatar.tsx
create mode 100644 .dumi/theme/slots/Content/Contributors.tsx
diff --git a/.dumi/theme/layouts/GlobalLayout.tsx b/.dumi/theme/layouts/GlobalLayout.tsx
index b6497a4be..80de7bb69 100644
--- a/.dumi/theme/layouts/GlobalLayout.tsx
+++ b/.dumi/theme/layouts/GlobalLayout.tsx
@@ -1,16 +1,39 @@
import React from 'react';
import { en_US, Web3ConfigProvider, zh_CN } from '@ant-design/web3-common';
-import { useIntl, useLocation, useOutlet, usePrefersColor } from 'dumi';
import { GlobalLayout as ThemeGlobalLayout } from 'dumi-theme-antd-web3';
+import { useIntl, useLocation, useOutlet, usePrefersColor, useRouteMeta } from 'dumi';
+import ReactDOM from 'react-dom/client';
import SiteThemeProvider from '../SiteThemeProvider';
+const Contributors = React.lazy(() => import('../slots/Content/Contributors'));
+
const GlobalLayout: React.FC = () => {
const outlet = useOutlet();
+ const meta = useRouteMeta();
const { pathname } = useLocation();
const [color] = usePrefersColor();
const { locale } = useIntl();
+ React.useEffect(() => {
+ const articleElement = document.querySelector('article');
+ const newContainer = document.createElement('div');
+
+ if (articleElement) {
+ // 在 article 元素后面创建一个新的容器
+ articleElement.parentNode?.insertBefore(newContainer, articleElement.nextSibling);
+
+ // 在新容器中渲染 Contributors 组件
+ const root = ReactDOM.createRoot(newContainer);
+ root.render();
+ }
+ return () => {
+ if (newContainer && articleElement) {
+ newContainer.remove();
+ }
+ };
+ }, [meta.frontmatter.filename]);
+
return (
diff --git a/.dumi/theme/slots/Content/ContributorAvatar.tsx b/.dumi/theme/slots/Content/ContributorAvatar.tsx
new file mode 100644
index 000000000..bc39c7a5c
--- /dev/null
+++ b/.dumi/theme/slots/Content/ContributorAvatar.tsx
@@ -0,0 +1,44 @@
+import React from 'react';
+import { Avatar, Skeleton, Tooltip } from 'antd';
+import type { AvatarListItem } from 'github-contributors-lists';
+
+const AvatarPlaceholder: React.FC<{ num?: number }> = ({ num = 3 }) => (
+
+ {Array.from({ length: num }).map((_, i) => (
+
+ ))}
+
+);
+
+interface ContributorAvatarProps {
+ loading?: boolean;
+ item?: AvatarListItem;
+}
+
+const ContributorAvatar: React.FC = (props) => {
+ const { item: { username, url } = {}, loading } = props;
+ if (loading) {
+ return ;
+ }
+ if (username?.includes('github-actions')) {
+ return null;
+ }
+ return (
+
+
+
+
+ {username}
+
+
+
+
+ );
+};
+
+export default ContributorAvatar;
diff --git a/.dumi/theme/slots/Content/Contributors.tsx b/.dumi/theme/slots/Content/Contributors.tsx
new file mode 100644
index 000000000..487377805
--- /dev/null
+++ b/.dumi/theme/slots/Content/Contributors.tsx
@@ -0,0 +1,65 @@
+import React from 'react';
+import { createStyles } from 'antd-style';
+import classNames from 'classnames';
+import ContributorsList from 'github-contributors-lists';
+
+import ContributorAvatar from './ContributorAvatar';
+
+const useStyle = createStyles(({ token, css }) => ({
+ contributorsList: css`
+ margin-top: 120px !important;
+ `,
+ listMobile: css`
+ margin: 1em 0 !important;
+ `,
+ title: css`
+ font-size: ${token.fontSizeSM}px;
+ opacity: 0.5;
+ margin-bottom: ${token.marginXS}px;
+ `,
+ list: css`
+ display: flex;
+ flex-wrap: wrap;
+ clear: both;
+ li {
+ height: 24px;
+ transition: all ${token.motionDurationSlow};
+ margin-inline-end: -${token.marginXS}px;
+ }
+ &:hover {
+ li {
+ margin-inline-end: 0;
+ }
+ }
+ `,
+}));
+
+interface ContributorsProps {
+ filename?: string;
+}
+
+const Contributors: React.FC = ({ filename }) => {
+ const { styles } = useStyle();
+
+ if (!filename) {
+ return null;
+ }
+
+ return (
+
+ (
+
+ )}
+ />
+
+ );
+};
+
+export default Contributors;
diff --git a/package.json b/package.json
index 6503226b5..2ef39cfd0 100644
--- a/package.json
+++ b/package.json
@@ -54,10 +54,10 @@
"@ant-design/web3": "workspace:*",
"@ant-design/web3-assets": "workspace:*",
"@ant-design/web3-common": "workspace:*",
+ "@ant-design/web3-ethers": "workspace:*",
"@ant-design/web3-icons": "workspace:*",
"@ant-design/web3-solana": "workspace:*",
"@ant-design/web3-wagmi": "workspace:*",
- "@ant-design/web3-ethers": "workspace:*",
"@biomejs/biome": "^1.6.4",
"@changesets/changelog-git": "^0.2.0",
"@changesets/cli": "^2.27.1",
@@ -84,6 +84,7 @@
"eslint-plugin-unused-imports": "^3.1.0",
"ethers": "^6.11.1",
"father": "^4.3.8",
+ "github-contributors-lists": "^1.0.3",
"husky": "^9.0.11",
"jsdom": "^24.0.0",
"lint-staged": "^15.2.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 061b41063..1e2794b2f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -114,6 +114,9 @@ importers:
father:
specifier: ^4.3.8
version: 4.3.8(@types/node@20.10.5)(webpack@5.91.0)
+ github-contributors-lists:
+ specifier: ^1.0.3
+ version: 1.0.3(react@18.2.0)
husky:
specifier: ^9.0.11
version: 9.0.11
@@ -17635,6 +17638,14 @@ packages:
remote-origin-url: 0.4.0
dev: true
+ /github-contributors-lists@1.0.3(react@18.2.0):
+ resolution: {integrity: sha512-6wcKgM7qgCXJ3ceBDOmqYCv6cuuTImlCc/znqC1QII0gx2a/g1eICo+aBUJX4EO8NIssgKxtmb6WsQPw5wVK+g==}
+ peerDependencies:
+ react: '>=16.0.0'
+ dependencies:
+ react: 18.2.0
+ dev: true
+
/github-slugger@1.5.0:
resolution: {integrity: sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==}
dev: true