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