Skip to content

Commit b5ed773

Browse files
committed
timeline keyboard improvement
1 parent e916d00 commit b5ed773

2 files changed

Lines changed: 24 additions & 22 deletions

File tree

web/js/components/preact/timeline/TimelineCursor.jsx

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,6 @@ export function TimelineCursor() {
3434
startHourRef.current = startHour;
3535
endHourRef.current = endHour;
3636

37-
// Debounce function to limit how often a function can be called
38-
const debounce = (func, delay) => {
39-
let timeoutId;
40-
return function(...args) {
41-
if (timeoutId) {
42-
clearTimeout(timeoutId);
43-
}
44-
timeoutId = setTimeout(() => {
45-
func.apply(this, args);
46-
}, delay);
47-
};
48-
};
49-
50-
// Create debounced version of updateCursorPosition
51-
const debouncedUpdateCursorPosition = useRef(
52-
debounce((time, startHr, endHr) => {
53-
updateCursorPosition(time, startHr, endHr);
54-
}, 100)
55-
).current;
56-
5737
// Subscribe to timeline state changes
5838
useEffect(() => {
5939
const unsubscribe = timelineState.subscribe(state => {
@@ -63,7 +43,7 @@ export function TimelineCursor() {
6343
// Only update current time if not dragging
6444
if (!isDraggingRef.current && !state.userControllingCursor) {
6545
updateTimeDisplay(state.currentTime);
66-
debouncedUpdateCursorPosition(
46+
updateCursorPosition(
6747
state.currentTime,
6848
state.timelineStartHour || 0,
6949
state.timelineEndHour || getTimelineDayLengthHours(state.selectedDate)
@@ -72,7 +52,7 @@ export function TimelineCursor() {
7252
});
7353

7454
return () => unsubscribe();
75-
}, [debouncedUpdateCursorPosition]);
55+
}, []);
7656

7757
// Set up drag handling
7858
useEffect(() => {

web/js/components/preact/timeline/TimelinePage.jsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,28 @@ export function TimelinePage() {
295295
return false;
296296
}
297297

298+
// Backward auto-advance: if seeking before the start of this segment, jump to the
299+
// end of the previous segment (mirrors how forward auto-advance works via handleEnded).
300+
if (directionSeconds < 0 && videoPlayer.currentTime + directionSeconds < 0) {
301+
const prevIndex = activeIndex - 1;
302+
const prevSegment = timelineState.timelineSegments?.[prevIndex];
303+
if (prevSegment) {
304+
const prevDuration = prevSegment.end_timestamp - prevSegment.start_timestamp;
305+
// Land 1 second before the end (magnitude of directionSeconds), clamped to [0, duration].
306+
const seekOffset = Math.max(prevDuration + directionSeconds, 0);
307+
timelineState.setState({
308+
currentSegmentIndex: prevIndex,
309+
currentTime: prevSegment.start_timestamp + seekOffset,
310+
prevCurrentTime: timelineState.currentTime,
311+
isPlaying: timelineState.isPlaying,
312+
forceReload: true
313+
});
314+
}
315+
// Return true whether or not there is a previous segment, so the browser
316+
// does not scroll the page on the key press.
317+
return true;
318+
}
319+
298320
const fallbackDuration = Math.max(activeSegment.end_timestamp - activeSegment.start_timestamp, 0);
299321
const effectiveDuration = Number.isFinite(videoPlayer.duration) && videoPlayer.duration > 0
300322
? videoPlayer.duration

0 commit comments

Comments
 (0)