@@ -36,7 +36,7 @@ import { ThemedTooltip } from "./Tooltip";
3636import ScrollContainer from "react-indiana-drag-scroll" ;
3737import CuttingActionsContextMenu from "./CuttingActionsContextMenu" ;
3838import { useHotkeys } from "react-hotkeys-hook" ;
39- import { Spinner } from "@opencast/appkit" ;
39+ import { ProtoButton , Spinner } from "@opencast/appkit" ;
4040import {
4141 selectSelectedSubtitleByIdForTimeline as chapterSelectSegments ,
4242 selectActiveSegmentIndex as chapterSelectActiveSegmentIndex ,
@@ -135,6 +135,15 @@ const Timeline: React.FC<{
135135 dispatch ( setCurrentlyAt ( ( offsetX / width ) * ( duration ) ) ) ;
136136 } ;
137137
138+ // Scroll the scroll container by its width one time
139+ // To be used when the scrubber moves out of sight while playing the video.
140+ const scrollByOwnWidth = ( ) => {
141+ if ( scrollContainerRef . current ) {
142+ scrollContainerRef . current . scrollLeft = scrollContainerRef . current ?. scrollLeft + scrollContainerWidth ;
143+ updateScroll ( ) ;
144+ }
145+ } ;
146+
138147 return (
139148 < ScrollContainer
140149 innerRef = { scrollContainerRef }
@@ -152,6 +161,9 @@ const Timeline: React.FC<{
152161 ref = { scrubberRef }
153162 timelineWidth = { width }
154163 timelineHeight = { timelineHeight }
164+ scrollContainerWidth = { scrollContainerWidth }
165+ scrollLeft = { scrollContainerRef . current ?. scrollLeft ?? 0 }
166+ scrollTheContainerbyOwnWidth = { scrollByOwnWidth }
155167 selectCurrentlyAt = { selectCurrentlyAt }
156168 selectIsPlaying = { selectIsPlaying }
157169 setCurrentlyAt = { setCurrentlyAt }
@@ -192,6 +204,9 @@ const Timeline: React.FC<{
192204type ScrubberProps = {
193205 timelineWidth : number ,
194206 timelineHeight : number ,
207+ scrollContainerWidth : number ,
208+ scrollLeft : number ,
209+ scrollTheContainerbyOwnWidth : ( ) => void ,
195210 selectCurrentlyAt : ( state : RootState ) => number ,
196211 selectIsPlaying : ( state : RootState ) => boolean ,
197212 setCurrentlyAt : ActionCreatorWithPayload < number , string > ,
@@ -203,7 +218,8 @@ type ScrubberProps = {
203218 * @param param0
204219 */
205220export const Scrubber = React . forwardRef < HTMLDivElement , ScrubberProps > ( ( props , nodeRef ) => {
206- const { timelineWidth, timelineHeight, selectCurrentlyAt, selectIsPlaying, setCurrentlyAt, setIsPlaying } = props ;
221+ const { timelineWidth, timelineHeight, scrollContainerWidth, scrollLeft, scrollTheContainerbyOwnWidth,
222+ selectCurrentlyAt, selectIsPlaying, setCurrentlyAt, setIsPlaying } = props ;
207223
208224 const { t } = useTranslation ( ) ;
209225
@@ -240,6 +256,14 @@ export const Scrubber = React.forwardRef<HTMLDivElement, ScrubberProps>((props,
240256 // eslint-disable-next-line react-hooks/exhaustive-deps
241257 } , [ timelineWidth ] ) ;
242258
259+ // Check when the scrubber moves out of sight (can happen when playing the video while zoomed in)
260+ // and then scroll the container
261+ useEffect ( ( ) => {
262+ if ( controlledPosition . x > ( scrollLeft + scrollContainerWidth ) ) {
263+ scrollTheContainerbyOwnWidth ( ) ;
264+ }
265+ } , [ controlledPosition . x , scrollContainerWidth , scrollLeft , scrollTheContainerbyOwnWidth ] ) ;
266+
243267 // Callback for when the scrubber gets dragged by the user
244268 const onControlledDrag : DraggableEventHandler = debounce ( ( _e , position : { x : number , y : number } ) => {
245269 // Update position
0 commit comments