@aidenlx/player
Version:
Headless web components that make integrating media on the a web a breeze.
173 lines (172 loc) • 5.48 kB
JavaScript
import {
__decorateClass
} from "../../chunks/chunk.LNH2V2XS.js";
import {
eventListener,
formatSpokenTime,
get,
isKeyboardEvent,
setAttributeIfEmpty,
throttle
} from "@vidstack/foundation";
import { property, state } from "lit/decorators.js";
import { mediaStoreSubscription } from "../../media";
import { SliderElement } from "../slider";
import { timeSliderElementStyles } from "./styles";
class TimespanSliderElement extends SliderElement {
constructor() {
super();
this._step = 0.1;
this.value = 0;
this.valueText = "{currentTime} out of {duration}";
this.pauseWhileDragging = false;
this.seekingRequestThrottle = 100;
this.__mediaDuration = 0;
this.__mediaPaused = true;
this._handleSliderDragStart = eventListener(this, "vds-slider-drag-start", (event) => {
this._togglePlaybackWhileDragging(event);
});
this._handleSliderValueChange = eventListener(this, "vds-slider-value-change", (event) => {
if (isKeyboardEvent(event.originEvent)) {
this._dispatchSeekingRequest.cancel();
this._mediaRemote.seek(this.value, event);
}
});
this._handleSliderDragValueChange = eventListener(this, "vds-slider-drag-value-change", (event) => {
this._dispatchSeekingRequest(event);
});
this._handleSliderDragEnd = eventListener(this, "vds-slider-drag-end", (event) => {
this._dispatchSeekingRequest.cancel();
this._mediaRemote.seek(this.value, event);
this._togglePlaybackWhileDragging(event);
});
this._dispatchSeekingRequest = throttle((event) => {
this._mediaRemote.seeking(this.value, event);
}, this.seekingRequestThrottle);
this._wasPlayingBeforeDragStart = false;
mediaStoreSubscription(this, "currentTime", ($currentTime) => {
if ($currentTime <= this.min) {
this.value = this.min;
} else if ($currentTime >= this.max) {
this.value = this.max;
} else {
this.value = $currentTime;
}
});
mediaStoreSubscription(this, "duration", ($duration) => {
this.__mediaDuration = $duration;
this.requestUpdate("max");
});
mediaStoreSubscription(this, "paused", ($paused) => {
this.__mediaPaused = $paused;
});
}
static get styles() {
return [super.styles, timeSliderElementStyles];
}
connectedCallback() {
super.connectedCallback();
setAttributeIfEmpty(this, "aria-label", "Media time");
}
get step() {
const range = this.max - this.min;
if (range > 5) {
return this._step;
} else if (range > 1) {
return 0.05;
} else {
return 0.01;
}
}
get min() {
const min = get(this.store.min);
if (typeof min === "number" && min > 0 && min < this.__mediaDuration)
return min;
else
return 0;
}
set min(newMin) {
if (newMin < 0)
newMin = 0;
else if (this.__mediaDuration > 0 && newMin > this.__mediaDuration)
newMin = this.__mediaDuration;
this.store.min.set(newMin);
}
get max() {
const max = get(this.store.max);
if (typeof max === "number" && max > 0 && max < this.__mediaDuration)
return max;
else
return this.__mediaDuration;
}
set max(newMax) {
if (newMax < 0)
newMax = 0;
else if (this.__mediaDuration > 0 && newMax > this.__mediaDuration)
newMax = this.__mediaDuration;
this.store.max.set(newMax);
}
update(changedProperties) {
if (changedProperties.has("disabled") && this.disabled) {
this._dispatchSeekingRequest.cancel();
}
super.update(changedProperties);
}
disconnectedCallback() {
this._dispatchSeekingRequest.cancel();
super.disconnectedCallback();
}
_getValueMin() {
return "0%";
}
_getValueNow() {
return `${Math.round(this.fillPercent)}%`;
}
_getValueText() {
return this.valueText.replace("{currentTime}", formatSpokenTime(this.value)).replace("{duration}", formatSpokenTime(this.__mediaDuration));
}
_getValueMax() {
return "100%";
}
_togglePlaybackWhileDragging(event) {
if (!this.pauseWhileDragging)
return;
if (this.isDragging && !this.__mediaPaused) {
this._wasPlayingBeforeDragStart = true;
this._mediaRemote.pause(event);
} else if (this._wasPlayingBeforeDragStart && !this.isDragging && this.__mediaPaused) {
this._wasPlayingBeforeDragStart = false;
this._mediaRemote.play(event);
}
}
}
__decorateClass([
property({ type: Number, reflect: true })
], TimespanSliderElement.prototype, "step", 1);
__decorateClass([
property({ attribute: false, state: true })
], TimespanSliderElement.prototype, "value", 2);
__decorateClass([
property({ reflect: true, type: Number })
], TimespanSliderElement.prototype, "min", 1);
__decorateClass([
property({ reflect: true, type: Number })
], TimespanSliderElement.prototype, "max", 1);
__decorateClass([
property({ attribute: "value-text" })
], TimespanSliderElement.prototype, "valueText", 2);
__decorateClass([
property({ attribute: "pause-while-dragging", type: Boolean })
], TimespanSliderElement.prototype, "pauseWhileDragging", 2);
__decorateClass([
property({ attribute: "seeking-request-throttle", type: Number })
], TimespanSliderElement.prototype, "seekingRequestThrottle", 2);
__decorateClass([
state()
], TimespanSliderElement.prototype, "__mediaDuration", 2);
__decorateClass([
state()
], TimespanSliderElement.prototype, "__mediaPaused", 2);
export {
TimespanSliderElement
};