diff --git a/docs_roll/package.json b/docs_roll/package.json index dc7096c9..7c5a10bf 100644 --- a/docs_roll/package.json +++ b/docs_roll/package.json @@ -27,6 +27,7 @@ "octokit": "^5.0.5", "prism-react-renderer": "^2.1.0", "react": "^18.2.0", + "react-countup": "^6.5.3", "react-dom": "^18.2.0" }, "devDependencies": { @@ -51,4 +52,4 @@ "engines": { "node": ">=18.0" } -} \ No newline at end of file +} diff --git a/docs_roll/scripts/update-stats.js b/docs_roll/scripts/update-stats.js index c4c61a66..31973289 100644 --- a/docs_roll/scripts/update-stats.js +++ b/docs_roll/scripts/update-stats.js @@ -66,6 +66,14 @@ async function main() { const totalPRs = prsAll.length; const openPRs = prsOpen.length; + // 5. Commits (all) + const commits = await octokit.paginate(octokit.rest.repos.listCommits, { + owner, + repo: repoName, + per_page: 100, + }); + const commitCount = commits.length; + // Pure issues = total issues - PRs const pureTotalIssues = totalIssues - totalPRs; const pureOpenIssues = openIssues - openPRs; @@ -87,6 +95,7 @@ async function main() { stars, forks, contributors: contributorCount, + commits: commitCount, issues: { total: pureTotalIssues, open: pureOpenIssues, diff --git a/docs_roll/src/components/HomeContent/index.js b/docs_roll/src/components/HomeContent/index.js index 8cc0932c..5dbfb71d 100644 --- a/docs_roll/src/components/HomeContent/index.js +++ b/docs_roll/src/components/HomeContent/index.js @@ -1,23 +1,71 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { Button, Image, Divider, Col, Row, Collapse, Modal, ConfigProvider, theme } from 'antd'; import { GithubOutlined, WechatOutlined, XOutlined } from '@ant-design/icons'; import clsx from 'clsx'; -import useBaseUrl from '@docusaurus/useBaseUrl'; import { useColorMode } from '@docusaurus/theme-common'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import Translate, { translate } from '@docusaurus/Translate'; -import Statistic from '../Statistic'; +import Translate from '@docusaurus/Translate'; +import dayjs from 'dayjs'; +import CountUp from 'react-countup'; import styles from './styles.module.css'; +// Intersection Observer Hook +const useIntersectionObserver = (options = {}) => { + const [isVisible, setIsVisible] = useState(false); + const elementRef = useRef(null); + + useEffect(() => { + const observer = new IntersectionObserver(([entry]) => { + if (entry.isIntersecting) { + setIsVisible(true); + observer.disconnect(); + } + }, { + threshold: 0.2, + rootMargin: '0px', + ...options + }); + + const currentElement = elementRef.current; + if (currentElement) { + observer.observe(currentElement); + } + + return () => { + if (currentElement) { + observer.unobserve(currentElement); + } + }; + }, [options]); + + return [elementRef, isVisible]; +}; + export default () => { const [open, setOpen] = useState(false); + const [todayStat, setTodayStat] = useState({}); + const today = dayjs().format('YYYY-MM-DD'); const { colorMode } = useColorMode(); const { i18n } = useDocusaurusContext(); const { currentLocale } = i18n; const isChinese = currentLocale !== 'en'; const targetPath = isChinese ? '/ROLL/zh-Hans/' : '/ROLL/' + // Intersection Observer refs + const [mainImgRef, mainImgVisible] = useIntersectionObserver(); + const [overviewRef, overviewVisible] = useIntersectionObserver(); + const [statsRef, statsVisible] = useIntersectionObserver(); + const [chooseRef, chooseVisible] = useIntersectionObserver(); + const [coreRef, coreVisible] = useIntersectionObserver(); + const [researchRef, researchVisible] = useIntersectionObserver(); + + useEffect(() => { + fetch('/ROLL/stats.json').then(res => res.json()).then(data => { + setTodayStat(data[today]); + }) + }, []); + return
@@ -52,11 +100,11 @@ export default () => {
-
+
-
+
ROLL
@@ -73,27 +121,42 @@ export default () => { -
+
- +
+ {statsVisible && } +
+
+ + Github Stars + +
- +
+ {statsVisible && } +
+
+ + Contributors + +
- +
+ {statsVisible && } +
+
+ + Commits + +
-
+
@@ -141,7 +204,7 @@ export default () => {
-
+
@@ -218,7 +281,7 @@ export default () => {
-
+
diff --git a/docs_roll/src/components/HomeContent/styles.module.css b/docs_roll/src/components/HomeContent/styles.module.css index ceb151e5..65bdcef9 100644 --- a/docs_roll/src/components/HomeContent/styles.module.css +++ b/docs_roll/src/components/HomeContent/styles.module.css @@ -57,6 +57,18 @@ } } + /* Fade in animation styles */ + .fadeIn { + opacity: 0; + transform: translateY(30px); + transition: opacity 0.8s ease-out, transform 0.8s ease-out; + } + + .fadeIn.visible { + opacity: 1; + transform: translateY(0); + } + .overview { margin-top: 40px; display: flex; @@ -218,4 +230,22 @@ } } } + .stats { + text-align: center; + margin-top: 110px; + padding-bottom: 80px; + .count { + color: var(--home-title-primary); + font-size: 44px; + font-weight: 600; + line-height: 54px; + margin-bottom: 20px; + } + .label { + color: var(--home-title-primary); + font-size: 16px; + font-weight: 500; + line-height: 24px; + } + } } \ No newline at end of file