@@ -1573,6 +1573,11 @@ export default function HomeClient({
15731573
15741574 const featuredCount = featuredProjects . length ;
15751575 const [ activeFeatured , setActiveFeatured ] = useState ( 0 ) ;
1576+ const featuredAutoTimerRef = useRef < number | null > ( null ) ;
1577+ const featuredAutoScheduleRef = useRef < ( ( delay : number ) => void ) | null > (
1578+ null ,
1579+ ) ;
1580+ const featuredLastInteractionRef = useRef ( 0 ) ;
15761581 const clampFeaturedIndex = useCallback (
15771582 ( index : number ) => {
15781583 if ( featuredCount <= 0 ) {
@@ -1594,22 +1599,55 @@ export default function HomeClient({
15941599 } ,
15951600 [ clampFeaturedIndex ] ,
15961601 ) ;
1602+ const registerFeaturedInteraction = useCallback ( ( ) => {
1603+ featuredLastInteractionRef . current = Date . now ( ) ;
1604+ if ( featuredAutoScheduleRef . current ) {
1605+ featuredAutoScheduleRef . current ( 12000 ) ;
1606+ }
1607+ } , [ ] ) ;
15971608 const featuredAutoDir = useRef ( 1 ) ;
15981609 useEffect ( ( ) => {
15991610 if ( reducedMotion || featuredCount <= 1 ) {
16001611 return ;
16011612 }
1602- const timer = window . setInterval ( ( ) => {
1603- setActiveFeatured ( ( prev ) => {
1604- if ( prev >= featuredCount - 1 ) {
1605- featuredAutoDir . current = - 1 ;
1606- } else if ( prev <= 0 ) {
1607- featuredAutoDir . current = 1 ;
1613+ let active = true ;
1614+ const clearTimer = ( ) => {
1615+ if ( featuredAutoTimerRef . current !== null ) {
1616+ window . clearTimeout ( featuredAutoTimerRef . current ) ;
1617+ featuredAutoTimerRef . current = null ;
1618+ }
1619+ } ;
1620+ const schedule = ( delay : number ) => {
1621+ clearTimer ( ) ;
1622+ featuredAutoTimerRef . current = window . setTimeout ( ( ) => {
1623+ if ( ! active ) {
1624+ return ;
16081625 }
1609- return clampFeaturedIndex ( prev + featuredAutoDir . current ) ;
1610- } ) ;
1611- } , 5200 ) ;
1612- return ( ) => window . clearInterval ( timer ) ;
1626+ const now = Date . now ( ) ;
1627+ const sinceInteraction =
1628+ now - ( featuredLastInteractionRef . current || 0 ) ;
1629+ if ( sinceInteraction < 12000 ) {
1630+ schedule ( 12000 - sinceInteraction ) ;
1631+ return ;
1632+ }
1633+ setActiveFeatured ( ( prev ) => {
1634+ if ( prev >= featuredCount - 1 ) {
1635+ featuredAutoDir . current = - 1 ;
1636+ } else if ( prev <= 0 ) {
1637+ featuredAutoDir . current = 1 ;
1638+ }
1639+ return clampFeaturedIndex ( prev + featuredAutoDir . current ) ;
1640+ } ) ;
1641+ schedule ( 5200 ) ;
1642+ } , delay ) ;
1643+ } ;
1644+ featuredAutoScheduleRef . current = schedule ;
1645+ schedule ( 5200 ) ;
1646+ return ( ) => {
1647+ active = false ;
1648+ featuredAutoScheduleRef . current = null ;
1649+ clearTimer ( ) ;
1650+ } ;
16131651 } , [ clampFeaturedIndex , featuredCount , reducedMotion ] ) ;
16141652 const safeActiveFeatured =
16151653 featuredCount > 0 ? clampFeaturedIndex ( activeFeatured ) : 0 ;
@@ -2412,7 +2450,10 @@ export default function HomeClient({
24122450 name = "featured-slider"
24132451 id = { `featured-slide-${ index + 1 } ` }
24142452 checked = { safeActiveFeatured === index }
2415- onChange = { ( ) => setFeaturedIndex ( index ) }
2453+ onChange = { ( ) => {
2454+ registerFeaturedInteraction ( ) ;
2455+ setFeaturedIndex ( index ) ;
2456+ } }
24162457 aria-label = { `${ t . sections . featured . title } ${ index + 1 } ` }
24172458 />
24182459 ) ) }
@@ -2437,7 +2478,10 @@ export default function HomeClient({
24372478 aria-label = { `${ t . sections . featured . title } ${
24382479 activeFeatured
24392480 } /${ featuredCount } `}
2440- onClick = { ( ) => shiftFeaturedIndex ( - 1 ) }
2481+ onClick = { ( ) => {
2482+ registerFeaturedInteraction ( ) ;
2483+ shiftFeaturedIndex ( - 1 ) ;
2484+ } }
24412485 />
24422486 ) : null }
24432487 { featuredProjects [ activeFeatured + 1 ] ? (
@@ -2447,7 +2491,10 @@ export default function HomeClient({
24472491 aria-label = { `${ t . sections . featured . title } ${
24482492 activeFeatured + 2
24492493 } /${ featuredCount } `}
2450- onClick = { ( ) => shiftFeaturedIndex ( 1 ) }
2494+ onClick = { ( ) => {
2495+ registerFeaturedInteraction ( ) ;
2496+ shiftFeaturedIndex ( 1 ) ;
2497+ } }
24512498 />
24522499 ) : null }
24532500 </ div >
@@ -2458,7 +2505,10 @@ export default function HomeClient({
24582505 aria-label = { `${ t . sections . featured . title } ${
24592506 safeActiveFeatured + 1
24602507 } /${ featuredCount } `}
2461- onClick = { ( ) => shiftFeaturedIndex ( - 1 ) }
2508+ onClick = { ( ) => {
2509+ registerFeaturedInteraction ( ) ;
2510+ shiftFeaturedIndex ( - 1 ) ;
2511+ } }
24622512 disabled = { safeActiveFeatured <= 0 } >
24632513 < svg viewBox = "0 0 24 24" aria-hidden = "true" >
24642514 < path
@@ -2485,7 +2535,10 @@ export default function HomeClient({
24852535 aria-label = { `${ t . sections . featured . title } ${
24862536 safeActiveFeatured + 1
24872537 } /${ featuredCount } `}
2488- onClick = { ( ) => shiftFeaturedIndex ( 1 ) }
2538+ onClick = { ( ) => {
2539+ registerFeaturedInteraction ( ) ;
2540+ shiftFeaturedIndex ( 1 ) ;
2541+ } }
24892542 disabled = { safeActiveFeatured >= featuredCount - 1 } >
24902543 < svg viewBox = "0 0 24 24" aria-hidden = "true" >
24912544 < path
0 commit comments