Skip to content

Commit e02cdea

Browse files
fix: reset progress bar on mobile scroll and pause on coming soon items (#2036)
- Add handleFeatureIndexChange in MainFeaturesSection to reset progress and pause on coming soon items - Add handleDetailIndexChange in DetailsSection with same behavior - Add handleTabIndexChange in FloatingPanelContent to reset progress on scroll - Update mobile carousels to use new handlers with index change check Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent 3e7f714 commit e02cdea

File tree

2 files changed

+59
-14
lines changed

2 files changed

+59
-14
lines changed

apps/web/src/routes/_view/index.tsx

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,9 +1092,24 @@ export function MainFeaturesSection({
10921092
scrollToFeature: (index: number) => void;
10931093
}) {
10941094
const [progress, setProgress] = useState(0);
1095+
const [isPaused, setIsPaused] = useState(false);
10951096
const progressRef = useRef(0);
10961097

1098+
const handleFeatureIndexChange = useCallback(
1099+
(nextIndex: number) => {
1100+
setSelectedFeature(nextIndex);
1101+
setProgress(0);
1102+
progressRef.current = 0;
1103+
1104+
const feature = mainFeatures[nextIndex];
1105+
setIsPaused(!!feature?.comingSoon);
1106+
},
1107+
[setSelectedFeature],
1108+
);
1109+
10971110
useEffect(() => {
1111+
if (isPaused) return;
1112+
10981113
const startTime =
10991114
Date.now() - (progressRef.current / 100) * FEATURES_AUTO_ADVANCE_DURATION;
11001115
let animationId: number;
@@ -1129,12 +1144,14 @@ export function MainFeaturesSection({
11291144

11301145
animationId = requestAnimationFrame(animate);
11311146
return () => cancelAnimationFrame(animationId);
1132-
}, [selectedFeature, setSelectedFeature, featuresScrollRef]);
1147+
}, [selectedFeature, setSelectedFeature, featuresScrollRef, isPaused]);
11331148

11341149
const handleScrollToFeature = (index: number) => {
11351150
scrollToFeature(index);
11361151
setProgress(0);
11371152
progressRef.current = 0;
1153+
const feature = mainFeatures[index];
1154+
setIsPaused(!!feature?.comingSoon);
11381155
};
11391156

11401157
return (
@@ -1161,7 +1178,7 @@ export function MainFeaturesSection({
11611178
<FeaturesMobileCarousel
11621179
featuresScrollRef={featuresScrollRef}
11631180
selectedFeature={selectedFeature}
1164-
setSelectedFeature={setSelectedFeature}
1181+
onIndexChange={handleFeatureIndexChange}
11651182
scrollToFeature={handleScrollToFeature}
11661183
progress={progress}
11671184
/>
@@ -1173,13 +1190,13 @@ export function MainFeaturesSection({
11731190
function FeaturesMobileCarousel({
11741191
featuresScrollRef,
11751192
selectedFeature,
1176-
setSelectedFeature,
1193+
onIndexChange,
11771194
scrollToFeature,
11781195
progress,
11791196
}: {
11801197
featuresScrollRef: React.RefObject<HTMLDivElement | null>;
11811198
selectedFeature: number;
1182-
setSelectedFeature: (index: number) => void;
1199+
onIndexChange: (index: number) => void;
11831200
scrollToFeature: (index: number) => void;
11841201
progress: number;
11851202
}) {
@@ -1193,7 +1210,9 @@ function FeaturesMobileCarousel({
11931210
const scrollLeft = container.scrollLeft;
11941211
const itemWidth = container.offsetWidth;
11951212
const index = Math.round(scrollLeft / itemWidth);
1196-
setSelectedFeature(index);
1213+
if (index !== selectedFeature) {
1214+
onIndexChange(index);
1215+
}
11971216
}}
11981217
>
11991218
<div className="flex">
@@ -1362,6 +1381,18 @@ export function DetailsSection({
13621381
const [isPaused, setIsPaused] = useState(false);
13631382
const progressRef = useRef(0);
13641383

1384+
const handleDetailIndexChange = useCallback(
1385+
(nextIndex: number) => {
1386+
setSelectedDetail(nextIndex);
1387+
setProgress(0);
1388+
progressRef.current = 0;
1389+
1390+
const feature = detailsFeatures[nextIndex];
1391+
setIsPaused(!!feature?.comingSoon);
1392+
},
1393+
[setSelectedDetail],
1394+
);
1395+
13651396
useEffect(() => {
13661397
if (isPaused) return;
13671398

@@ -1404,12 +1435,16 @@ export function DetailsSection({
14041435
setSelectedDetail(index);
14051436
setProgress(0);
14061437
progressRef.current = 0;
1438+
const feature = detailsFeatures[index];
1439+
setIsPaused(!!feature?.comingSoon);
14071440
};
14081441

14091442
const handleScrollToDetail = (index: number) => {
14101443
scrollToDetail(index);
14111444
setProgress(0);
14121445
progressRef.current = 0;
1446+
const feature = detailsFeatures[index];
1447+
setIsPaused(!!feature?.comingSoon);
14131448
};
14141449

14151450
return (
@@ -1418,7 +1453,7 @@ export function DetailsSection({
14181453
<DetailsMobileCarousel
14191454
detailsScrollRef={detailsScrollRef}
14201455
selectedDetail={selectedDetail}
1421-
setSelectedDetail={setSelectedDetail}
1456+
onIndexChange={handleDetailIndexChange}
14221457
scrollToDetail={handleScrollToDetail}
14231458
progress={progress}
14241459
/>
@@ -1450,13 +1485,13 @@ function DetailsSectionHeader() {
14501485
function DetailsMobileCarousel({
14511486
detailsScrollRef,
14521487
selectedDetail,
1453-
setSelectedDetail,
1488+
onIndexChange,
14541489
scrollToDetail,
14551490
progress,
14561491
}: {
14571492
detailsScrollRef: React.RefObject<HTMLDivElement | null>;
14581493
selectedDetail: number;
1459-
setSelectedDetail: (index: number) => void;
1494+
onIndexChange: (index: number) => void;
14601495
scrollToDetail: (index: number) => void;
14611496
progress: number;
14621497
}) {
@@ -1470,7 +1505,9 @@ function DetailsMobileCarousel({
14701505
const scrollLeft = container.scrollLeft;
14711506
const itemWidth = container.offsetWidth;
14721507
const index = Math.round(scrollLeft / itemWidth);
1473-
setSelectedDetail(index);
1508+
if (index !== selectedDetail) {
1509+
onIndexChange(index);
1510+
}
14741511
}}
14751512
>
14761513
<div className="flex">

apps/web/src/routes/_view/product/ai-notetaking.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
SearchIcon,
88
} from "lucide-react";
99
import { AnimatePresence, motion } from "motion/react";
10-
import { memo, useEffect, useRef, useState } from "react";
10+
import { memo, useCallback, useEffect, useRef, useState } from "react";
1111

1212
import { Typewriter } from "@hypr/ui/components/ui/typewriter";
1313
import { cn } from "@hypr/utils";
@@ -2215,6 +2215,12 @@ function FloatingPanelContent() {
22152215
const scrollRef = useRef<HTMLDivElement>(null);
22162216
const progressRef = useRef(0);
22172217

2218+
const handleTabIndexChange = useCallback((nextIndex: number) => {
2219+
setSelectedTab(nextIndex);
2220+
setProgress(0);
2221+
progressRef.current = 0;
2222+
}, []);
2223+
22182224
useEffect(() => {
22192225
if (isPaused) return;
22202226

@@ -2272,7 +2278,7 @@ function FloatingPanelContent() {
22722278
<FloatingPanelMobile
22732279
scrollRef={scrollRef}
22742280
selectedTab={selectedTab}
2275-
setSelectedTab={setSelectedTab}
2281+
onIndexChange={handleTabIndexChange}
22762282
scrollToTab={scrollToTab}
22772283
progress={progress}
22782284
/>
@@ -2446,13 +2452,13 @@ function FloatingPanelDesktop() {
24462452
function FloatingPanelMobile({
24472453
scrollRef,
24482454
selectedTab,
2449-
setSelectedTab,
2455+
onIndexChange,
24502456
scrollToTab,
24512457
progress,
24522458
}: {
24532459
scrollRef: React.RefObject<HTMLDivElement | null>;
24542460
selectedTab: number;
2455-
setSelectedTab: (index: number) => void;
2461+
onIndexChange: (index: number) => void;
24562462
scrollToTab: (index: number) => void;
24572463
progress: number;
24582464
}) {
@@ -2466,7 +2472,9 @@ function FloatingPanelMobile({
24662472
const scrollLeft = container.scrollLeft;
24672473
const itemWidth = container.offsetWidth;
24682474
const index = Math.round(scrollLeft / itemWidth);
2469-
setSelectedTab(index);
2475+
if (index !== selectedTab) {
2476+
onIndexChange(index);
2477+
}
24702478
}}
24712479
>
24722480
<div className="flex">

0 commit comments

Comments
 (0)