1- import React , { useState } from 'react' ;
1+ import React , { useState , useEffect , useRef } from 'react' ;
22import { Button , Image , Divider , Col , Row , Collapse , Modal , ConfigProvider , theme } from 'antd' ;
33import { GithubOutlined , WechatOutlined , XOutlined } from '@ant-design/icons' ;
44import clsx from 'clsx' ;
5- import useBaseUrl from '@docusaurus/useBaseUrl' ;
65import { useColorMode } from '@docusaurus/theme-common' ;
76import useDocusaurusContext from '@docusaurus/useDocusaurusContext' ;
8- import Translate , { translate } from '@docusaurus/Translate' ;
9- import Statistic from '../Statistic' ;
7+ import Translate from '@docusaurus/Translate' ;
8+ import dayjs from 'dayjs' ;
9+ import CountUp from 'react-countup' ;
1010
1111import styles from './styles.module.css' ;
1212
13+ // Intersection Observer Hook
14+ const useIntersectionObserver = ( options = { } ) => {
15+ const [ isVisible , setIsVisible ] = useState ( false ) ;
16+ const elementRef = useRef ( null ) ;
17+
18+ useEffect ( ( ) => {
19+ const observer = new IntersectionObserver ( ( [ entry ] ) => {
20+ if ( entry . isIntersecting ) {
21+ setIsVisible ( true ) ;
22+ observer . disconnect ( ) ;
23+ }
24+ } , {
25+ threshold : 0.2 ,
26+ rootMargin : '0px' ,
27+ ...options
28+ } ) ;
29+
30+ const currentElement = elementRef . current ;
31+ if ( currentElement ) {
32+ observer . observe ( currentElement ) ;
33+ }
34+
35+ return ( ) => {
36+ if ( currentElement ) {
37+ observer . unobserve ( currentElement ) ;
38+ }
39+ } ;
40+ } , [ options ] ) ;
41+
42+ return [ elementRef , isVisible ] ;
43+ } ;
44+
1345export default ( ) => {
1446 const [ open , setOpen ] = useState ( false ) ;
47+ const [ todayStat , setTodayStat ] = useState ( { } ) ;
48+ const today = dayjs ( ) . format ( 'YYYY-MM-DD' ) ;
1549 const { colorMode } = useColorMode ( ) ;
1650 const { i18n } = useDocusaurusContext ( ) ;
1751 const { currentLocale } = i18n ;
1852 const isChinese = currentLocale !== 'en' ;
1953 const targetPath = isChinese ? '/ROLL/zh-Hans/' : '/ROLL/'
2054
55+ // Intersection Observer refs
56+ const [ mainImgRef , mainImgVisible ] = useIntersectionObserver ( ) ;
57+ const [ overviewRef , overviewVisible ] = useIntersectionObserver ( ) ;
58+ const [ statsRef , statsVisible ] = useIntersectionObserver ( ) ;
59+ const [ chooseRef , chooseVisible ] = useIntersectionObserver ( ) ;
60+ const [ coreRef , coreVisible ] = useIntersectionObserver ( ) ;
61+ const [ researchRef , researchVisible ] = useIntersectionObserver ( ) ;
62+
63+ useEffect ( ( ) => {
64+ fetch ( '/ROLL/stats.json' ) . then ( res => res . json ( ) ) . then ( data => {
65+ setTodayStat ( data [ today ] ) ;
66+ } )
67+ } , [ ] ) ;
68+
2169 return < ConfigProvider theme = { { algorithm : colorMode === 'dark' ? theme . darkAlgorithm : theme . defaultAlgorithm } } >
2270 < div className = { clsx ( 'container' , styles . container ) } id = "home" >
2371 < div >
@@ -52,11 +100,11 @@ export default () => {
52100 < Button className = { styles . github } target = '_blank' href = "https://deepwiki.com/alibaba/ROLL" variant = "outlined" icon = { < Image width = { 14 } src = "https://img.alicdn.com/imgextra/i3/O1CN01JUBft41wYcExwXCOK_!!6000000006320-55-tps-460-500.svg" preview = { false } > </ Image > } > { "DeepWiki >" } </ Button >
53101 </ div >
54102
55- < div className = { styles . mainImg } >
103+ < div ref = { mainImgRef } className = { clsx ( styles . mainImg , styles . fadeIn , mainImgVisible && styles . visible ) } >
56104 < Image className = { styles . img } src = "https://img.alicdn.com/imgextra/i2/O1CN01ZGW6zG1sXSmML15c3_!!6000000005776-2-tps-2160-1112.png" preview = { false } > </ Image >
57105 </ div >
58106
59- < div className = { styles . overview } >
107+ < div ref = { overviewRef } className = { clsx ( styles . overview , styles . fadeIn , overviewVisible && styles . visible ) } >
60108 < div className = { styles . left } >
61109 < Image className = { styles . img } src = "https://img.alicdn.com/imgextra/i4/O1CN01t4tcSz1ZIN1sEzNnO_!!6000000003171-55-tps-54-54.svg" preview = { false } > </ Image >
62110 < div > ROLL</ div >
@@ -73,27 +121,42 @@ export default () => {
73121
74122 < Divider style = { { borderColor : 'var(--home-divider-color)' } } > </ Divider >
75123
76- < div >
124+ < div ref = { statsRef } className = { styles . stats } >
77125 < Row gutter = { 16 } >
78126 < Col span = { 8 } >
79- < Statistic count = "1.9k" content = { translate ( {
80- message : 'Github Stars' ,
81- } ) } />
127+ < div className = { styles . count } >
128+ { statsVisible && < CountUp end = { todayStat ?. stars || 2620 } /> }
129+ </ div >
130+ < div className = { styles . label } >
131+ < Translate >
132+ Github Stars
133+ </ Translate >
134+ </ div >
82135 </ Col >
83136 < Col span = { 8 } >
84- < Statistic count = "30+" content = { translate ( {
85- message : 'Contributors' ,
86- } ) } />
137+ < div className = { styles . count } >
138+ { statsVisible && < CountUp end = { todayStat ?. contributors || 37 } /> }
139+ </ div >
140+ < div className = { styles . label } >
141+ < Translate >
142+ Contributors
143+ </ Translate >
144+ </ div >
87145 </ Col >
88146 < Col span = { 8 } >
89- < Statistic count = "200+" content = { translate ( {
90- message : 'Commits' ,
91- } ) } />
147+ < div className = { styles . count } >
148+ { statsVisible && < CountUp end = { todayStat ?. commits || 371 } /> }
149+ </ div >
150+ < div className = { styles . label } >
151+ < Translate >
152+ Commits
153+ </ Translate >
154+ </ div >
92155 </ Col >
93156 </ Row >
94157 </ div >
95158
96- < div className = { styles . choose } >
159+ < div ref = { chooseRef } className = { clsx ( styles . choose , styles . fadeIn , chooseVisible && styles . visible ) } >
97160 < Image className = { styles . img } src = "https://img.alicdn.com/imgextra/i3/O1CN01NwkUFs26qbxZhsz2J_!!6000000007713-55-tps-54-54.svg" preview = { false } > </ Image >
98161 < div className = { styles . wrap } >
99162 < div className = { styles . left } >
@@ -141,7 +204,7 @@ export default () => {
141204 </ div >
142205 </ div >
143206
144- < div className = { styles . core } id = "core" >
207+ < div ref = { coreRef } className = { clsx ( styles . core , styles . fadeIn , coreVisible && styles . visible ) } id = "core" >
145208 < Image className = { styles . img } src = "https://img.alicdn.com/imgextra/i4/O1CN012UiWaS1KzDqk2EhyO_!!6000000001234-55-tps-54-54.svg" preview = { false } > </ Image >
146209 < div >
147210 < div className = { styles . title } >
@@ -218,7 +281,7 @@ export default () => {
218281 </ div >
219282 </ div >
220283
221- < div className = { styles . research } id = "research" >
284+ < div ref = { researchRef } className = { clsx ( styles . research , styles . fadeIn , researchVisible && styles . visible ) } id = "research" >
222285 < Image className = { styles . img } src = "https://img.alicdn.com/imgextra/i1/O1CN016cZT1g1tk7L6GRZ7y_!!6000000005939-55-tps-54-54.svg" preview = { false } > </ Image >
223286 < div >
224287 < div className = { styles . title } >
0 commit comments