feat: release v0.0.1
This commit is contained in:
8
dist/react/video-player/components/video-js/plugins/skip-buttons/index.d.ts
vendored
Normal file
8
dist/react/video-player/components/video-js/plugins/skip-buttons/index.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import Player from "video.js/dist/types/player";
|
||||
import "./skip-buttons.css";
|
||||
export interface SkipButtonsOptions {
|
||||
skip: number;
|
||||
}
|
||||
declare const skipButtonsPlugin: (this: Player, options: SkipButtonsOptions) => void;
|
||||
export default skipButtonsPlugin;
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
dist/react/video-player/components/video-js/plugins/skip-buttons/index.d.ts.map
vendored
Normal file
1
dist/react/video-player/components/video-js/plugins/skip-buttons/index.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/react/video-player/components/video-js/plugins/skip-buttons/index.tsx"],"names":[],"mappings":"AAKA,OAAO,MAAM,MAAM,4BAA4B,CAAC;AAKhD,OAAO,oBAAoB,CAAC;AAM5B,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;CACb;AAgID,QAAA,MAAM,iBAAiB,GAAa,MAAM,MAAM,EAAE,SAAS,kBAAkB,SAsD5E,CAAC;AAIF,eAAe,iBAAiB,CAAC"}
|
||||
145
dist/react/video-player/components/video-js/plugins/skip-buttons/index.js
vendored
Normal file
145
dist/react/video-player/components/video-js/plugins/skip-buttons/index.js
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
||||
// skipButtonsPlugin.tsx
|
||||
import React from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import videojs from "video.js";
|
||||
import BackwardSvg from "./skip-backward.svg";
|
||||
import ForwardSvg from "./skip-forward.svg";
|
||||
import "./skip-buttons.css";
|
||||
import { numWord } from "../../../../shared/math";
|
||||
const renderSvg = (asset) => {
|
||||
if (typeof asset === "string") {
|
||||
return _jsx("img", { src: asset, alt: "", "aria-hidden": "true" });
|
||||
}
|
||||
const SvgComponent = asset;
|
||||
return _jsx(SvgComponent, {});
|
||||
};
|
||||
const SkipButton = ({ player, skip, direction }) => {
|
||||
// Накопленная сумма перемотки
|
||||
const [accumulated, setAccumulated] = React.useState(0);
|
||||
// Храним ID таймера debounce
|
||||
const timerRef = React.useRef(null);
|
||||
// Используем ref для мгновенного доступа к накопленному значению
|
||||
const accumulatedRef = React.useRef(0);
|
||||
const handleClick = () => {
|
||||
// Вычисляем новое накопленное значение
|
||||
const newAccumulated = direction === "forward"
|
||||
? accumulatedRef.current + skip
|
||||
: accumulatedRef.current - skip;
|
||||
accumulatedRef.current = newAccumulated;
|
||||
setAccumulated(newAccumulated);
|
||||
// Сбрасываем предыдущий таймер
|
||||
if (timerRef.current) {
|
||||
clearTimeout(timerRef.current);
|
||||
}
|
||||
// Устанавливаем debounce (500 мс)
|
||||
timerRef.current = setTimeout(() => {
|
||||
const currentTime = player.currentTime() || 0;
|
||||
const newTime = currentTime + accumulatedRef.current;
|
||||
player.currentTime(newTime);
|
||||
// Сбрасываем накопленное значение
|
||||
accumulatedRef.current = 0;
|
||||
setAccumulated(0);
|
||||
}, 500);
|
||||
};
|
||||
return (_jsxs("button", { onClick: handleClick, className: `vjs-skip-button vjs-skip-button-${direction}`, children: [_jsx("span", { className: "icon-placeholder", children: skip }), accumulated ? (_jsxs("div", { className: "scroll-info", children: [direction === "backward"
|
||||
? renderSvg(BackwardSvg)
|
||||
: renderSvg(ForwardSvg), `${Math.abs(accumulated)} ${numWord(accumulated, ["секунду", "секунды", "секунд"])}`] })) : null] }));
|
||||
};
|
||||
// Базовый Video.js компонент, обёртывающий React-компонент
|
||||
class SkipButtonComponent extends videojs.getComponent("Component") {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.reactRoot = null;
|
||||
}
|
||||
createEl() {
|
||||
const direction = this.options_.direction;
|
||||
const el = super.createEl("div", {
|
||||
className: `vjs-skip-button-component vjs-skip-${direction}`,
|
||||
});
|
||||
// Рендерим React-компонент сразу внутри созданного элемента
|
||||
this.reactRoot = createRoot(el);
|
||||
this.reactRoot.render(_jsx(SkipButton, { player: this.player(), skip: this.options_.skip, direction: direction }));
|
||||
return el;
|
||||
}
|
||||
dispose() {
|
||||
if (this.reactRoot) {
|
||||
this.reactRoot.unmount();
|
||||
this.reactRoot = null;
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
// Компонент для кнопки перемотки назад – задаём direction через options
|
||||
class SkipBackwardButtonComponent extends SkipButtonComponent {
|
||||
constructor(player, options) {
|
||||
options.direction = "backward";
|
||||
super(player, options);
|
||||
}
|
||||
}
|
||||
// Компонент для кнопки перемотки вперёд – задаём direction через options
|
||||
class SkipForwardButtonComponent extends SkipButtonComponent {
|
||||
constructor(player, options) {
|
||||
options.direction = "forward";
|
||||
super(player, options);
|
||||
}
|
||||
}
|
||||
// Регистрируем компоненты в Video.js
|
||||
videojs.registerComponent("SkipBackwardButtonComponent", SkipBackwardButtonComponent);
|
||||
videojs.registerComponent("SkipForwardButtonComponent", SkipForwardButtonComponent);
|
||||
// Плагин, который добавляет два отдельных компонента через player.addChild
|
||||
const skipButtonsPlugin = function (options) {
|
||||
const player = this;
|
||||
player.ready(() => {
|
||||
// 1) Добавляем кнопки
|
||||
player.addChild("SkipBackwardButtonComponent", { skip: options.skip });
|
||||
player.addChild("SkipForwardButtonComponent", { skip: options.skip });
|
||||
// 2) Вспомогательная функция, которая находит кнопку и вызывает click()
|
||||
const triggerSkipClick = (direction) => {
|
||||
// Ищем именно <button class="vjs-skip-button vjs-skip-button-{direction}">
|
||||
const selector = `.vjs-skip-button-${direction}`;
|
||||
const btn = player.el().querySelector(selector);
|
||||
if (btn)
|
||||
btn.click();
|
||||
};
|
||||
// 3) Обработка стрелок
|
||||
const onKeydown = (e) => {
|
||||
// Если фокус в инпуте/textarea/select или contenteditable — выходим
|
||||
const active = document.activeElement;
|
||||
const tag = active?.tagName;
|
||||
const isEditable = tag === "INPUT" ||
|
||||
tag === "TEXTAREA" ||
|
||||
tag === "SELECT" ||
|
||||
active?.getAttribute("contenteditable") === "true";
|
||||
if (isEditable)
|
||||
return;
|
||||
if (e.key === " " || e.code === "Space") {
|
||||
player.el()?.focus();
|
||||
e.preventDefault();
|
||||
if (player.paused())
|
||||
player.play();
|
||||
else
|
||||
player.pause();
|
||||
return;
|
||||
}
|
||||
if (e.key === "ArrowRight") {
|
||||
player.el()?.focus();
|
||||
e.preventDefault();
|
||||
triggerSkipClick("forward");
|
||||
}
|
||||
else if (e.key === "ArrowLeft") {
|
||||
player.el()?.focus();
|
||||
e.preventDefault();
|
||||
triggerSkipClick("backward");
|
||||
}
|
||||
};
|
||||
document.addEventListener("keydown", onKeydown);
|
||||
// 4) Убираем слушатель при dispose
|
||||
player.on("dispose", () => {
|
||||
document.removeEventListener("keydown", onKeydown);
|
||||
});
|
||||
});
|
||||
};
|
||||
videojs.registerPlugin("skipButtons", skipButtonsPlugin);
|
||||
export default skipButtonsPlugin;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
dist/react/video-player/components/video-js/plugins/skip-buttons/index.js.map
vendored
Normal file
1
dist/react/video-player/components/video-js/plugins/skip-buttons/index.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
15
dist/react/video-player/components/video-js/plugins/skip-buttons/skip-backward.svg
vendored
Normal file
15
dist/react/video-player/components/video-js/plugins/skip-buttons/skip-backward.svg
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"
|
||||
style="width: 20%; max-width: 48px; height: auto;" fill="none">
|
||||
<path
|
||||
d="M41.1751 35.3188C40.5985 35.3188 40.1204 35.1359 39.5579 34.7984L25.2282 26.361C24.2298 25.7704 23.7938 25.0812 23.7938 24.2656C23.7938 23.4641 24.2298 22.775 25.2282 22.1844L39.5579 13.7469C40.1344 13.4094 40.5985 13.2266 41.1751 13.2266C42.2719 13.2266 43.2001 14.0703 43.2001 15.6312V32.9141C43.2001 34.475 42.2719 35.3188 41.1751 35.3188ZM21.8532 35.3188C21.2767 35.3188 20.7985 35.1359 20.236 34.7984L5.89231 26.361C4.90783 25.7704 4.47199 25.0812 4.47199 24.2656C4.47199 23.4641 4.90783 22.775 5.89231 22.1844L20.236 13.7469C20.7985 13.4094 21.2767 13.2266 21.8532 13.2266C22.9501 13.2266 23.8782 14.0703 23.8782 15.6312V32.9141C23.8782 34.475 22.9501 35.3188 21.8532 35.3188Z"
|
||||
fill="url(#paint0_linear_17944_473880)" />
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_17944_473880" x1="43.2001" y1="23.9984" x2="4.80007"
|
||||
y2="23.9984" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" />
|
||||
<stop offset="0.49" stop-color="white" />
|
||||
<stop offset="0.5" stop-color="white" stop-opacity="0.3" />
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.3" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
115
dist/react/video-player/components/video-js/plugins/skip-buttons/skip-buttons.css
vendored
Normal file
115
dist/react/video-player/components/video-js/plugins/skip-buttons/skip-buttons.css
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
.video-js {
|
||||
.vjs-skip-button-component {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: calc(50% - 48px);
|
||||
height: calc(100% - 73px);
|
||||
|
||||
opacity: 1;
|
||||
transition: opacity 1s;
|
||||
|
||||
&.vjs-skip-backward {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&.vjs-skip-forward {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.vjs-skip-button {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.icon-placeholder {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
align-content: center;
|
||||
position: absolute;
|
||||
top: calc(50% + calc(48px / 2));
|
||||
}
|
||||
|
||||
.scroll-info {
|
||||
width: 100%;
|
||||
height: calc(100% + 73px);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
||||
padding: 6%;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
|
||||
align-content: center;
|
||||
|
||||
color: var(--Light-theme-Default-White, #fff);
|
||||
text-align: center;
|
||||
/* app/bold/Headline */
|
||||
font-family: Inter;
|
||||
font-size: 1.3vw;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
font-size: 1vw;
|
||||
}
|
||||
}
|
||||
|
||||
&.vjs-skip-button-backward {
|
||||
.icon-placeholder {
|
||||
right: 10px;
|
||||
background-repeat: no-repeat;
|
||||
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M31.8191 5.58705C29.3458 4.53678 26.6859 3.99697 23.9988 4.00001C17.4569 4.00039 11.6487 7.14174 8 11.9982V8.00001C8 6.89544 7.10457 6.00001 6 6.00001C4.89543 6.00001 4 6.89544 4 8.00001V24C4 25.1046 4.89543 26 6 26C7.10457 26 8 25.1046 8 24C8 15.1636 15.1636 8.00001 24 8.00001L24.0024 8.00001C26.151 7.99745 28.278 8.42902 30.2557 9.26884C32.2334 10.1087 34.021 11.3394 35.5113 12.8872C36.2774 13.6829 37.5435 13.7069 38.3392 12.9407C39.1349 12.1746 39.1589 10.9085 38.3927 10.1128C36.5287 8.17687 34.2928 6.63748 31.8191 5.58705ZM42 22C40.8954 22 40 22.8954 40 24C40 32.8364 32.8364 40 24 40H23.9973C19.8528 40.0056 15.8691 38.3968 12.8908 35.5148C12.0971 34.7466 10.8309 34.7674 10.0628 35.5612C9.29464 36.3549 9.31542 37.6211 10.1092 38.3892C13.8348 41.9945 18.8182 44.007 24.0027 44L24 42V44H24.0027C35.047 43.9985 44 35.0447 44 24C44 22.8954 43.1046 22 42 22Z' fill='white'/%3E%3C/svg%3E") no-repeat center / 24px 24px;
|
||||
}
|
||||
.scroll-info {
|
||||
left: -65%;
|
||||
align-items: end;
|
||||
background: linear-gradient(
|
||||
270deg,
|
||||
rgba(0, 0, 0, 0.25) 0%,
|
||||
rgba(0, 0, 0, 0) 73.42%
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
&.vjs-skip-button-forward {
|
||||
.icon-placeholder {
|
||||
left: 10px;
|
||||
background-repeat: no-repeat;
|
||||
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M16.1809 5.58705C18.6542 4.53678 21.3141 3.99697 24.0012 4.00001C30.5431 4.00039 36.3513 7.14174 40 11.9982V8.00001C40 6.89544 40.8954 6.00001 42 6.00001C43.1046 6.00001 44 6.89544 44 8.00001V24C44 25.1046 43.1046 26 42 26C40.8954 26 40 25.1046 40 24C40 15.1636 32.8364 8.00001 24 8.00001L23.9976 8.00001C21.849 7.99745 19.722 8.42902 17.7443 9.26884C15.7666 10.1087 13.979 11.3394 12.4887 12.8872C11.7226 13.6829 10.4565 13.7069 9.66082 12.9407C8.86512 12.1746 8.84114 10.9085 9.60727 10.1128C11.4713 8.17687 13.7072 6.63748 16.1809 5.58705ZM6 22C7.10457 22 8 22.8954 8 24C8 32.8364 15.1636 40 24 40H24.0027C28.1472 40.0056 32.1309 38.3968 35.1092 35.5148C35.9029 34.7466 37.1691 34.7674 37.9372 35.5612C38.7054 36.3549 38.6846 37.6211 37.8908 38.3892C34.1652 41.9945 29.1818 44.007 23.9973 44L24 42V44H23.9973C12.953 43.9985 4 35.0447 4 24C4 22.8954 4.89543 22 6 22Z' fill='white'/%3E%3C/svg%3E") no-repeat center / 24px 24px;
|
||||
}
|
||||
.scroll-info {
|
||||
align-items: start;
|
||||
right: -65%;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(0, 0, 0, 0.25) 0%,
|
||||
rgba(0, 0, 0, 0) 73.42%
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.vjs-user-inactive {
|
||||
.vjs-skip-button-component {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* &.vjs-hls-live, */
|
||||
&.vjs-controls-disabled {
|
||||
.vjs-skip-button-component {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
dist/react/video-player/components/video-js/plugins/skip-buttons/skip-forward.svg
vendored
Normal file
15
dist/react/video-player/components/video-js/plugins/skip-buttons/skip-forward.svg
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="width: 20%; max-width: 48px; height: auto;"
|
||||
viewBox="0 0 48 48" fill="none">
|
||||
<path
|
||||
d="M2.82499 22.3188C3.40155 22.3188 3.87968 22.1359 4.44218 21.7984L18.7719 13.361C19.7703 12.7704 20.2063 12.0812 20.2063 11.2656C20.2063 10.4641 19.7703 9.775 18.7719 9.18437L4.44218 0.746875C3.86562 0.409375 3.40155 0.226562 2.82499 0.226562C1.72811 0.226562 0.799988 1.07031 0.799988 2.63125V19.9141C0.799988 21.475 1.72811 22.3188 2.82499 22.3188ZM22.1469 22.3188C22.7234 22.3188 23.2016 22.1359 23.764 21.7984L38.1077 13.361C39.0922 12.7704 39.5281 12.0812 39.5281 11.2656C39.5281 10.4641 39.0922 9.775 38.1077 9.18437L23.764 0.746875C23.2016 0.409375 22.7234 0.226562 22.1469 0.226562C21.05 0.226562 20.1219 1.07031 20.1219 2.63125V19.9141C20.1219 21.475 21.05 22.3188 22.1469 22.3188Z"
|
||||
fill="url(#paint0_linear_17959_7312)" />
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_17959_7312" x1="0.799988" y1="10.9984" x2="39.2" y2="10.9984"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" />
|
||||
<stop offset="0.49" stop-color="white" />
|
||||
<stop offset="0.5" stop-color="white" stop-opacity="0.3" />
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.3" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
Reference in New Issue
Block a user