Skip to content

Commit 5d70279

Browse files
committed
fix(player): forward global keyboard events to slider correctly and bound value
ref #965
1 parent fce730f commit 5d70279

4 files changed

Lines changed: 39 additions & 13 deletions

File tree

packages/vidstack/src/components/ui/sliders/slider/events-controller.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ export class SliderEventsController extends ViewController<
268268
}
269269

270270
const value = this._getKeyValue(event);
271-
if (!value) return;
271+
if (isUndefined(value)) return;
272272

273273
const repeat = key === this._lastDownKey;
274274
if (!this.$state.dragging() && repeat) this._onStartDragging(value, event);
@@ -302,7 +302,7 @@ export class SliderEventsController extends ViewController<
302302
if (!isValidKey) return;
303303

304304
const { shiftKeyMultiplier } = this.$props;
305-
const { value } = this.$state,
305+
const { value, min, max } = this.$state,
306306
step = this._delegate._getStep(),
307307
keyStep = this._delegate._getKeyStep();
308308

@@ -311,7 +311,7 @@ export class SliderEventsController extends ViewController<
311311
diff = modifiedStep * direction,
312312
steps = (value() + diff) / step;
313313

314-
return Number((step * steps).toFixed(3));
314+
return Math.max(min(), Math.min(max(), Number((step * steps).toFixed(3))));
315315
}
316316

317317
// -------------------------------------------------------------------------------------------

packages/vidstack/src/components/ui/sliders/time-slider/time-slider.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ export class TimeSlider extends Component<
4242
> {
4343
static props: TimeSliderProps = {
4444
...SliderController.props,
45+
step: 0.1,
46+
keyStep: 5,
47+
shiftKeyMultiplier: 2,
4548
pauseWhileDragging: false,
4649
seekingRequestThrottle: 100,
4750
};

packages/vidstack/src/components/ui/sliders/volume-slider.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,12 @@ export class VolumeSlider extends Component<
3636
SliderEvents,
3737
SliderCSSVars
3838
> {
39-
static props: VolumeSliderProps = SliderController.props;
39+
static props: VolumeSliderProps = {
40+
...SliderController.props,
41+
keyStep: 5,
42+
shiftKeyMultiplier: 2,
43+
};
44+
4045
static state = sliderState;
4146

4247
private _media!: MediaContext;

packages/vidstack/src/core/keyboard/controller.ts

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { effect, peek, signal } from 'maverick.js';
2-
import { DOMEvent, isKeyboardClick, listenEvent } from 'maverick.js/std';
2+
import { isKeyboardClick, listenEvent } from 'maverick.js/std';
33

44
import { isHTMLMediaElement } from '../../providers/type-check';
55
import type { MediaContext } from '../api/media-context';
@@ -80,7 +80,7 @@ export class MediaKeyboardController extends MediaPlayerController {
8080
event.preventDefault();
8181
event.stopPropagation();
8282
if (this._timeSlider) {
83-
this._forwardTimeKeyboardEvent(event);
83+
this._forwardTimeKeyboardEvent(event, method === 'seekForward');
8484
this._timeSlider = null;
8585
} else {
8686
this._media.remote.seek(this._seekTotal!, event);
@@ -90,7 +90,13 @@ export class MediaKeyboardController extends MediaPlayerController {
9090

9191
if (method?.startsWith('volume')) {
9292
const volumeSlider = this.el!.querySelector('[data-media-volume-slider]');
93-
volumeSlider?.dispatchEvent(new DOMEvent<void>('keyup', { trigger: event }));
93+
volumeSlider?.dispatchEvent(
94+
new KeyboardEvent('keyup', {
95+
key: method === 'volumeUp' ? 'Up' : 'Down',
96+
shiftKey: event.shiftKey,
97+
trigger: event,
98+
} as KeyboardEventInit),
99+
);
94100
}
95101
}
96102

@@ -124,13 +130,19 @@ export class MediaKeyboardController extends MediaPlayerController {
124130
switch (method) {
125131
case 'seekForward':
126132
case 'seekBackward':
127-
this._seeking(event, method);
133+
this._seeking(event, method, method === 'seekForward');
128134
break;
129135
case 'volumeUp':
130136
case 'volumeDown':
131137
const volumeSlider = this.el!.querySelector('[data-media-volume-slider]');
132138
if (volumeSlider) {
133-
volumeSlider.dispatchEvent(new DOMEvent<void>('keydown', { trigger: event }));
139+
volumeSlider.dispatchEvent(
140+
new KeyboardEvent('keydown', {
141+
key: method === 'volumeUp' ? 'Up' : 'Down',
142+
shiftKey: event.shiftKey,
143+
trigger: event,
144+
} as KeyboardEventInit),
145+
);
134146
} else {
135147
const value = event.shiftKey ? 0.1 : 0.05;
136148
this._media.remote.changeVolume(
@@ -187,15 +199,21 @@ export class MediaKeyboardController extends MediaPlayerController {
187199
}
188200

189201
private _timeSlider: Element | null = null;
190-
private _forwardTimeKeyboardEvent(event: KeyboardEvent) {
191-
this._timeSlider?.dispatchEvent(new DOMEvent<void>(event.type, { trigger: event }));
202+
private _forwardTimeKeyboardEvent(event: KeyboardEvent, forward: boolean) {
203+
this._timeSlider?.dispatchEvent(
204+
new KeyboardEvent(event.type, {
205+
key: !forward ? 'Left' : 'Right',
206+
shiftKey: event.shiftKey,
207+
trigger: event,
208+
} as KeyboardEventInit),
209+
);
192210
}
193211

194-
private _seeking(event: KeyboardEvent, type: string) {
212+
private _seeking(event: KeyboardEvent, type: string, forward: boolean) {
195213
if (!this.$state.canSeek()) return;
196214
if (!this._timeSlider) this._timeSlider = this.el!.querySelector('[data-media-time-slider]');
197215
if (this._timeSlider) {
198-
this._forwardTimeKeyboardEvent(event);
216+
this._forwardTimeKeyboardEvent(event, forward);
199217
} else {
200218
this._media.remote.seeking(this._calcSeekAmount(event, type), event);
201219
}

0 commit comments

Comments
 (0)