analytica-frontend-lib 1.1.10 → 1.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/VideoPlayer/index.js +347 -183
- package/dist/VideoPlayer/index.js.map +1 -1
- package/dist/VideoPlayer/index.mjs +353 -184
- package/dist/VideoPlayer/index.mjs.map +1 -1
- package/dist/index.css +3 -3
- package/dist/index.css.map +1 -1
- package/dist/index.js +347 -183
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +353 -184
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +3 -3
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6832,6 +6832,85 @@ var formatTime = (seconds) => {
|
|
|
6832
6832
|
const secs = Math.floor(seconds % 60);
|
|
6833
6833
|
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
6834
6834
|
};
|
|
6835
|
+
var ProgressBar2 = ({
|
|
6836
|
+
currentTime,
|
|
6837
|
+
duration,
|
|
6838
|
+
progressPercentage,
|
|
6839
|
+
onSeek
|
|
6840
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "px-4 pb-2", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6841
|
+
"input",
|
|
6842
|
+
{
|
|
6843
|
+
type: "range",
|
|
6844
|
+
min: 0,
|
|
6845
|
+
max: duration || 100,
|
|
6846
|
+
value: currentTime,
|
|
6847
|
+
onChange: (e) => onSeek(parseFloat(e.target.value)),
|
|
6848
|
+
className: "w-full h-1 bg-neutral-600 rounded-full appearance-none cursor-pointer slider:bg-primary-600 focus:outline-none focus:ring-2 focus:ring-primary-500",
|
|
6849
|
+
"aria-label": "Video progress",
|
|
6850
|
+
style: {
|
|
6851
|
+
background: `linear-gradient(to right, var(--color-primary-700) ${progressPercentage}%, var(--color-secondary-300) ${progressPercentage}%)`
|
|
6852
|
+
}
|
|
6853
|
+
}
|
|
6854
|
+
) });
|
|
6855
|
+
var VolumeControls = ({
|
|
6856
|
+
volume,
|
|
6857
|
+
isMuted,
|
|
6858
|
+
onVolumeChange,
|
|
6859
|
+
onToggleMute
|
|
6860
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
6861
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6862
|
+
IconButton_default,
|
|
6863
|
+
{
|
|
6864
|
+
icon: isMuted ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_phosphor_react18.SpeakerSlash, { size: 24 }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_phosphor_react18.SpeakerHigh, { size: 24 }),
|
|
6865
|
+
onClick: onToggleMute,
|
|
6866
|
+
"aria-label": isMuted ? "Unmute" : "Mute",
|
|
6867
|
+
className: "!bg-transparent !text-white hover:!bg-white/20"
|
|
6868
|
+
}
|
|
6869
|
+
),
|
|
6870
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6871
|
+
"input",
|
|
6872
|
+
{
|
|
6873
|
+
type: "range",
|
|
6874
|
+
min: 0,
|
|
6875
|
+
max: 100,
|
|
6876
|
+
value: Math.round(volume * 100),
|
|
6877
|
+
onChange: (e) => onVolumeChange(parseInt(e.target.value)),
|
|
6878
|
+
className: "w-20 h-1 bg-neutral-600 rounded-full appearance-none cursor-pointer focus:outline-none focus:ring-2 focus:ring-primary-500",
|
|
6879
|
+
"aria-label": "Volume control",
|
|
6880
|
+
style: {
|
|
6881
|
+
background: `linear-gradient(to right, var(--color-primary-700) ${volume * 100}%, var(--color-secondary-300) ${volume * 100}%)`
|
|
6882
|
+
}
|
|
6883
|
+
}
|
|
6884
|
+
)
|
|
6885
|
+
] });
|
|
6886
|
+
var SpeedMenu = ({
|
|
6887
|
+
showSpeedMenu,
|
|
6888
|
+
playbackRate,
|
|
6889
|
+
onToggleMenu,
|
|
6890
|
+
onSpeedChange
|
|
6891
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "relative", children: [
|
|
6892
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
6893
|
+
IconButton_default,
|
|
6894
|
+
{
|
|
6895
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_phosphor_react18.DotsThreeVertical, { size: 24 }),
|
|
6896
|
+
onClick: onToggleMenu,
|
|
6897
|
+
"aria-label": "Playback speed",
|
|
6898
|
+
className: "!bg-transparent !text-white hover:!bg-white/20"
|
|
6899
|
+
}
|
|
6900
|
+
),
|
|
6901
|
+
showSpeedMenu && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "absolute bottom-12 right-0 bg-black/90 rounded-lg p-2 min-w-20", children: [0.5, 0.75, 1, 1.25, 1.5, 2].map((speed) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
6902
|
+
"button",
|
|
6903
|
+
{
|
|
6904
|
+
onClick: () => onSpeedChange(speed),
|
|
6905
|
+
className: `block w-full text-left px-3 py-1 text-sm rounded hover:bg-white/20 transition-colors ${playbackRate === speed ? "text-primary-400" : "text-white"}`,
|
|
6906
|
+
children: [
|
|
6907
|
+
speed,
|
|
6908
|
+
"x"
|
|
6909
|
+
]
|
|
6910
|
+
},
|
|
6911
|
+
speed
|
|
6912
|
+
)) })
|
|
6913
|
+
] });
|
|
6835
6914
|
var VideoPlayer = ({
|
|
6836
6915
|
src,
|
|
6837
6916
|
poster,
|
|
@@ -6856,10 +6935,51 @@ var VideoPlayer = ({
|
|
|
6856
6935
|
const [showControls, setShowControls] = (0, import_react22.useState)(true);
|
|
6857
6936
|
const [hasCompleted, setHasCompleted] = (0, import_react22.useState)(false);
|
|
6858
6937
|
const [showCaptions, setShowCaptions] = (0, import_react22.useState)(false);
|
|
6938
|
+
(0, import_react22.useEffect)(() => {
|
|
6939
|
+
setHasCompleted(false);
|
|
6940
|
+
}, [src]);
|
|
6859
6941
|
const [playbackRate, setPlaybackRate] = (0, import_react22.useState)(1);
|
|
6860
6942
|
const [showSpeedMenu, setShowSpeedMenu] = (0, import_react22.useState)(false);
|
|
6861
6943
|
const lastSaveTimeRef = (0, import_react22.useRef)(0);
|
|
6862
6944
|
const trackRef = (0, import_react22.useRef)(null);
|
|
6945
|
+
const controlsTimeoutRef = (0, import_react22.useRef)(null);
|
|
6946
|
+
const lastMousePositionRef = (0, import_react22.useRef)({ x: 0, y: 0 });
|
|
6947
|
+
const mouseMoveTimeoutRef = (0, import_react22.useRef)(null);
|
|
6948
|
+
const clearControlsTimeout = (0, import_react22.useCallback)(() => {
|
|
6949
|
+
if (controlsTimeoutRef.current) {
|
|
6950
|
+
clearTimeout(controlsTimeoutRef.current);
|
|
6951
|
+
controlsTimeoutRef.current = null;
|
|
6952
|
+
}
|
|
6953
|
+
}, []);
|
|
6954
|
+
const clearMouseMoveTimeout = (0, import_react22.useCallback)(() => {
|
|
6955
|
+
if (mouseMoveTimeoutRef.current) {
|
|
6956
|
+
clearTimeout(mouseMoveTimeoutRef.current);
|
|
6957
|
+
mouseMoveTimeoutRef.current = null;
|
|
6958
|
+
}
|
|
6959
|
+
}, []);
|
|
6960
|
+
const showControlsWithTimer = (0, import_react22.useCallback)(() => {
|
|
6961
|
+
setShowControls(true);
|
|
6962
|
+
clearControlsTimeout();
|
|
6963
|
+
if (isPlaying) {
|
|
6964
|
+
const timeout = isFullscreen ? 2e3 : 3e3;
|
|
6965
|
+
controlsTimeoutRef.current = window.setTimeout(() => {
|
|
6966
|
+
setShowControls(false);
|
|
6967
|
+
}, timeout);
|
|
6968
|
+
}
|
|
6969
|
+
}, [isPlaying, isFullscreen, clearControlsTimeout]);
|
|
6970
|
+
const handleMouseMove = (0, import_react22.useCallback)(
|
|
6971
|
+
(event) => {
|
|
6972
|
+
const currentX = event.clientX;
|
|
6973
|
+
const currentY = event.clientY;
|
|
6974
|
+
const lastPos = lastMousePositionRef.current;
|
|
6975
|
+
const hasMoved = Math.abs(currentX - lastPos.x) > 5 || Math.abs(currentY - lastPos.y) > 5;
|
|
6976
|
+
if (hasMoved) {
|
|
6977
|
+
lastMousePositionRef.current = { x: currentX, y: currentY };
|
|
6978
|
+
showControlsWithTimer();
|
|
6979
|
+
}
|
|
6980
|
+
},
|
|
6981
|
+
[showControlsWithTimer]
|
|
6982
|
+
);
|
|
6863
6983
|
(0, import_react22.useEffect)(() => {
|
|
6864
6984
|
if (videoRef.current) {
|
|
6865
6985
|
videoRef.current.volume = volume;
|
|
@@ -6867,84 +6987,129 @@ var VideoPlayer = ({
|
|
|
6867
6987
|
}
|
|
6868
6988
|
}, [volume, isMuted]);
|
|
6869
6989
|
(0, import_react22.useEffect)(() => {
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
const
|
|
6873
|
-
const
|
|
6874
|
-
const
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6990
|
+
const video = videoRef.current;
|
|
6991
|
+
if (!video) return;
|
|
6992
|
+
const onPlay = () => setIsPlaying(true);
|
|
6993
|
+
const onPause = () => setIsPlaying(false);
|
|
6994
|
+
const onEnded = () => setIsPlaying(false);
|
|
6995
|
+
video.addEventListener("play", onPlay);
|
|
6996
|
+
video.addEventListener("pause", onPause);
|
|
6997
|
+
video.addEventListener("ended", onEnded);
|
|
6998
|
+
return () => {
|
|
6999
|
+
video.removeEventListener("play", onPlay);
|
|
7000
|
+
video.removeEventListener("pause", onPause);
|
|
7001
|
+
video.removeEventListener("ended", onEnded);
|
|
7002
|
+
};
|
|
7003
|
+
}, []);
|
|
7004
|
+
(0, import_react22.useEffect)(() => {
|
|
7005
|
+
if (isPlaying) {
|
|
7006
|
+
showControlsWithTimer();
|
|
6880
7007
|
} else {
|
|
6881
|
-
|
|
7008
|
+
clearControlsTimeout();
|
|
7009
|
+
setShowControls(true);
|
|
7010
|
+
}
|
|
7011
|
+
}, [isPlaying, showControlsWithTimer, clearControlsTimeout]);
|
|
7012
|
+
(0, import_react22.useEffect)(() => {
|
|
7013
|
+
const handleFullscreenChange = () => {
|
|
7014
|
+
const isCurrentlyFullscreen = !!document.fullscreenElement;
|
|
7015
|
+
setIsFullscreen(isCurrentlyFullscreen);
|
|
7016
|
+
if (isCurrentlyFullscreen) {
|
|
7017
|
+
showControlsWithTimer();
|
|
7018
|
+
}
|
|
7019
|
+
};
|
|
7020
|
+
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
|
7021
|
+
return () => {
|
|
7022
|
+
document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
|
7023
|
+
};
|
|
7024
|
+
}, [showControlsWithTimer]);
|
|
7025
|
+
const getInitialTime = (0, import_react22.useCallback)(() => {
|
|
7026
|
+
if (!autoSave || !storageKey) {
|
|
7027
|
+
return Number.isFinite(initialTime) && initialTime >= 0 ? initialTime : void 0;
|
|
6882
7028
|
}
|
|
7029
|
+
const saved = Number(localStorage.getItem(`${storageKey}-${src}`) || NaN);
|
|
7030
|
+
const hasValidInitial = Number.isFinite(initialTime) && initialTime >= 0;
|
|
7031
|
+
const hasValidSaved = Number.isFinite(saved) && saved >= 0;
|
|
7032
|
+
if (hasValidInitial) return initialTime;
|
|
7033
|
+
if (hasValidSaved) return saved;
|
|
7034
|
+
return void 0;
|
|
7035
|
+
}, [autoSave, storageKey, src, initialTime]);
|
|
7036
|
+
(0, import_react22.useEffect)(() => {
|
|
7037
|
+
const start = getInitialTime();
|
|
6883
7038
|
if (start !== void 0 && videoRef.current) {
|
|
6884
7039
|
videoRef.current.currentTime = start;
|
|
6885
7040
|
setCurrentTime(start);
|
|
6886
7041
|
}
|
|
6887
|
-
}, [
|
|
6888
|
-
const saveProgress = (0, import_react22.useCallback)(
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
}, [autoSave, storageKey, src, currentTime]);
|
|
6896
|
-
const togglePlayPause = (0, import_react22.useCallback)(() => {
|
|
6897
|
-
if (videoRef.current) {
|
|
6898
|
-
if (isPlaying) {
|
|
6899
|
-
videoRef.current.pause();
|
|
6900
|
-
} else {
|
|
6901
|
-
videoRef.current.play();
|
|
7042
|
+
}, [getInitialTime]);
|
|
7043
|
+
const saveProgress = (0, import_react22.useCallback)(
|
|
7044
|
+
(time) => {
|
|
7045
|
+
if (!autoSave || !storageKey) return;
|
|
7046
|
+
const now = Date.now();
|
|
7047
|
+
if (now - lastSaveTimeRef.current > 5e3) {
|
|
7048
|
+
localStorage.setItem(`${storageKey}-${src}`, time.toString());
|
|
7049
|
+
lastSaveTimeRef.current = now;
|
|
6902
7050
|
}
|
|
6903
|
-
|
|
7051
|
+
},
|
|
7052
|
+
[autoSave, storageKey, src]
|
|
7053
|
+
);
|
|
7054
|
+
const togglePlayPause = (0, import_react22.useCallback)(async () => {
|
|
7055
|
+
const video = videoRef.current;
|
|
7056
|
+
if (!video) return;
|
|
7057
|
+
if (!video.paused) {
|
|
7058
|
+
video.pause();
|
|
7059
|
+
return;
|
|
7060
|
+
}
|
|
7061
|
+
try {
|
|
7062
|
+
await video.play();
|
|
7063
|
+
} catch {
|
|
6904
7064
|
}
|
|
6905
|
-
}, [
|
|
7065
|
+
}, []);
|
|
6906
7066
|
const handleVolumeChange = (0, import_react22.useCallback)(
|
|
6907
7067
|
(newVolume) => {
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
7068
|
+
const video = videoRef.current;
|
|
7069
|
+
if (!video) return;
|
|
7070
|
+
const volumeValue = newVolume / 100;
|
|
7071
|
+
video.volume = volumeValue;
|
|
7072
|
+
setVolume(volumeValue);
|
|
7073
|
+
const shouldMute = volumeValue === 0;
|
|
7074
|
+
const shouldUnmute = volumeValue > 0 && isMuted;
|
|
7075
|
+
if (shouldMute) {
|
|
7076
|
+
video.muted = true;
|
|
7077
|
+
setIsMuted(true);
|
|
7078
|
+
} else if (shouldUnmute) {
|
|
7079
|
+
video.muted = false;
|
|
7080
|
+
setIsMuted(false);
|
|
6919
7081
|
}
|
|
6920
7082
|
},
|
|
6921
7083
|
[isMuted]
|
|
6922
7084
|
);
|
|
6923
7085
|
const toggleMute = (0, import_react22.useCallback)(() => {
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
7086
|
+
const video = videoRef.current;
|
|
7087
|
+
if (!video) return;
|
|
7088
|
+
if (isMuted) {
|
|
7089
|
+
const restoreVolume = volume > 0 ? volume : 0.5;
|
|
7090
|
+
video.volume = restoreVolume;
|
|
7091
|
+
video.muted = false;
|
|
7092
|
+
setVolume(restoreVolume);
|
|
7093
|
+
setIsMuted(false);
|
|
7094
|
+
} else {
|
|
7095
|
+
video.muted = true;
|
|
7096
|
+
setIsMuted(true);
|
|
6935
7097
|
}
|
|
6936
7098
|
}, [isMuted, volume]);
|
|
7099
|
+
const handleSeek = (0, import_react22.useCallback)((newTime) => {
|
|
7100
|
+
const video = videoRef.current;
|
|
7101
|
+
if (video) {
|
|
7102
|
+
video.currentTime = newTime;
|
|
7103
|
+
}
|
|
7104
|
+
}, []);
|
|
6937
7105
|
const toggleFullscreen = (0, import_react22.useCallback)(() => {
|
|
6938
7106
|
const container = videoRef.current?.parentElement;
|
|
6939
7107
|
if (!container) return;
|
|
6940
|
-
if (!isFullscreen) {
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
}
|
|
6944
|
-
} else if (document.exitFullscreen) {
|
|
7108
|
+
if (!isFullscreen && container.requestFullscreen) {
|
|
7109
|
+
container.requestFullscreen();
|
|
7110
|
+
} else if (isFullscreen && document.exitFullscreen) {
|
|
6945
7111
|
document.exitFullscreen();
|
|
6946
7112
|
}
|
|
6947
|
-
setIsFullscreen(!isFullscreen);
|
|
6948
7113
|
}, [isFullscreen]);
|
|
6949
7114
|
const handleSpeedChange = (0, import_react22.useCallback)((speed) => {
|
|
6950
7115
|
if (videoRef.current) {
|
|
@@ -6962,29 +7127,28 @@ var VideoPlayer = ({
|
|
|
6962
7127
|
setShowCaptions(newShowCaptions);
|
|
6963
7128
|
trackRef.current.track.mode = newShowCaptions && subtitles ? "showing" : "hidden";
|
|
6964
7129
|
}, [showCaptions, subtitles]);
|
|
6965
|
-
const
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
onTimeUpdate?.(current);
|
|
6971
|
-
if (duration > 0) {
|
|
6972
|
-
const progressPercent = current / duration * 100;
|
|
6973
|
-
onProgress?.(progressPercent);
|
|
6974
|
-
if (progressPercent >= 95 && !hasCompleted) {
|
|
6975
|
-
setHasCompleted(true);
|
|
6976
|
-
onVideoComplete?.();
|
|
6977
|
-
}
|
|
7130
|
+
const checkVideoCompletion = (0, import_react22.useCallback)(
|
|
7131
|
+
(progressPercent) => {
|
|
7132
|
+
if (progressPercent >= 95 && !hasCompleted) {
|
|
7133
|
+
setHasCompleted(true);
|
|
7134
|
+
onVideoComplete?.();
|
|
6978
7135
|
}
|
|
7136
|
+
},
|
|
7137
|
+
[hasCompleted, onVideoComplete]
|
|
7138
|
+
);
|
|
7139
|
+
const handleTimeUpdate = (0, import_react22.useCallback)(() => {
|
|
7140
|
+
const video = videoRef.current;
|
|
7141
|
+
if (!video) return;
|
|
7142
|
+
const current = video.currentTime;
|
|
7143
|
+
setCurrentTime(current);
|
|
7144
|
+
saveProgress(current);
|
|
7145
|
+
onTimeUpdate?.(current);
|
|
7146
|
+
if (duration > 0) {
|
|
7147
|
+
const progressPercent = current / duration * 100;
|
|
7148
|
+
onProgress?.(progressPercent);
|
|
7149
|
+
checkVideoCompletion(progressPercent);
|
|
6979
7150
|
}
|
|
6980
|
-
}, [
|
|
6981
|
-
duration,
|
|
6982
|
-
saveProgress,
|
|
6983
|
-
onTimeUpdate,
|
|
6984
|
-
onProgress,
|
|
6985
|
-
onVideoComplete,
|
|
6986
|
-
hasCompleted
|
|
6987
|
-
]);
|
|
7151
|
+
}, [duration, saveProgress, onTimeUpdate, onProgress, checkVideoCompletion]);
|
|
6988
7152
|
const handleLoadedMetadata = (0, import_react22.useCallback)(() => {
|
|
6989
7153
|
if (videoRef.current) {
|
|
6990
7154
|
setDuration(videoRef.current.duration);
|
|
@@ -7013,9 +7177,78 @@ var VideoPlayer = ({
|
|
|
7013
7177
|
return () => {
|
|
7014
7178
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
7015
7179
|
window.removeEventListener("blur", handleBlur);
|
|
7180
|
+
clearControlsTimeout();
|
|
7181
|
+
clearMouseMoveTimeout();
|
|
7016
7182
|
};
|
|
7017
|
-
}, [isPlaying]);
|
|
7183
|
+
}, [isPlaying, clearControlsTimeout, clearMouseMoveTimeout]);
|
|
7018
7184
|
const progressPercentage = duration > 0 ? currentTime / duration * 100 : 0;
|
|
7185
|
+
const getTopControlsOpacity = (0, import_react22.useCallback)(() => {
|
|
7186
|
+
if (isFullscreen) {
|
|
7187
|
+
return showControls ? "opacity-100" : "opacity-0";
|
|
7188
|
+
}
|
|
7189
|
+
return !isPlaying || showControls ? "opacity-100" : "opacity-0 group-hover:opacity-100";
|
|
7190
|
+
}, [isFullscreen, showControls, isPlaying]);
|
|
7191
|
+
const getBottomControlsOpacity = (0, import_react22.useCallback)(() => {
|
|
7192
|
+
if (isFullscreen) {
|
|
7193
|
+
return showControls ? "opacity-100" : "opacity-0";
|
|
7194
|
+
}
|
|
7195
|
+
return !isPlaying || showControls ? "opacity-100" : "opacity-0 group-hover:opacity-100";
|
|
7196
|
+
}, [isFullscreen, showControls, isPlaying]);
|
|
7197
|
+
const handleVideoKeyDown = (0, import_react22.useCallback)(
|
|
7198
|
+
(e) => {
|
|
7199
|
+
if (e.key) {
|
|
7200
|
+
e.stopPropagation();
|
|
7201
|
+
showControlsWithTimer();
|
|
7202
|
+
}
|
|
7203
|
+
switch (e.key) {
|
|
7204
|
+
case " ":
|
|
7205
|
+
case "Enter":
|
|
7206
|
+
e.preventDefault();
|
|
7207
|
+
togglePlayPause();
|
|
7208
|
+
break;
|
|
7209
|
+
case "ArrowLeft":
|
|
7210
|
+
e.preventDefault();
|
|
7211
|
+
if (videoRef.current) {
|
|
7212
|
+
videoRef.current.currentTime -= 10;
|
|
7213
|
+
}
|
|
7214
|
+
break;
|
|
7215
|
+
case "ArrowRight":
|
|
7216
|
+
e.preventDefault();
|
|
7217
|
+
if (videoRef.current) {
|
|
7218
|
+
videoRef.current.currentTime += 10;
|
|
7219
|
+
}
|
|
7220
|
+
break;
|
|
7221
|
+
case "ArrowUp":
|
|
7222
|
+
e.preventDefault();
|
|
7223
|
+
handleVolumeChange(Math.min(100, volume * 100 + 10));
|
|
7224
|
+
break;
|
|
7225
|
+
case "ArrowDown":
|
|
7226
|
+
e.preventDefault();
|
|
7227
|
+
handleVolumeChange(Math.max(0, volume * 100 - 10));
|
|
7228
|
+
break;
|
|
7229
|
+
case "m":
|
|
7230
|
+
case "M":
|
|
7231
|
+
e.preventDefault();
|
|
7232
|
+
toggleMute();
|
|
7233
|
+
break;
|
|
7234
|
+
case "f":
|
|
7235
|
+
case "F":
|
|
7236
|
+
e.preventDefault();
|
|
7237
|
+
toggleFullscreen();
|
|
7238
|
+
break;
|
|
7239
|
+
default:
|
|
7240
|
+
break;
|
|
7241
|
+
}
|
|
7242
|
+
},
|
|
7243
|
+
[
|
|
7244
|
+
showControlsWithTimer,
|
|
7245
|
+
togglePlayPause,
|
|
7246
|
+
handleVolumeChange,
|
|
7247
|
+
volume,
|
|
7248
|
+
toggleMute,
|
|
7249
|
+
toggleFullscreen
|
|
7250
|
+
]
|
|
7251
|
+
);
|
|
7019
7252
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: cn("flex flex-col", className), children: [
|
|
7020
7253
|
(title || subtitleText) && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "bg-subject-1 rounded-t-xl px-8 py-4 flex items-end justify-between min-h-20", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
7021
7254
|
title && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
@@ -7042,12 +7275,17 @@ var VideoPlayer = ({
|
|
|
7042
7275
|
)
|
|
7043
7276
|
] }) }),
|
|
7044
7277
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
7045
|
-
"
|
|
7278
|
+
"section",
|
|
7046
7279
|
{
|
|
7047
7280
|
className: cn(
|
|
7048
7281
|
"relative w-full bg-background overflow-hidden group",
|
|
7049
|
-
title || subtitleText ? "rounded-b-xl" : "rounded-xl"
|
|
7282
|
+
title || subtitleText ? "rounded-b-xl" : "rounded-xl",
|
|
7283
|
+
// Hide cursor when controls are hidden and video is playing in fullscreen
|
|
7284
|
+
isFullscreen && isPlaying && !showControls ? "cursor-none" : "cursor-default"
|
|
7050
7285
|
),
|
|
7286
|
+
"aria-label": title ? `Video player: ${title}` : "Video player",
|
|
7287
|
+
onMouseMove: isFullscreen ? handleMouseMove : showControlsWithTimer,
|
|
7288
|
+
onMouseEnter: showControlsWithTimer,
|
|
7051
7289
|
children: [
|
|
7052
7290
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7053
7291
|
"video",
|
|
@@ -7060,39 +7298,7 @@ var VideoPlayer = ({
|
|
|
7060
7298
|
onTimeUpdate: handleTimeUpdate,
|
|
7061
7299
|
onLoadedMetadata: handleLoadedMetadata,
|
|
7062
7300
|
onClick: togglePlayPause,
|
|
7063
|
-
onKeyDown:
|
|
7064
|
-
if (e.key) {
|
|
7065
|
-
setShowControls(true);
|
|
7066
|
-
}
|
|
7067
|
-
if (e.key === " " || e.key === "Enter") {
|
|
7068
|
-
e.preventDefault();
|
|
7069
|
-
togglePlayPause();
|
|
7070
|
-
}
|
|
7071
|
-
if (e.key === "ArrowLeft" && videoRef.current) {
|
|
7072
|
-
e.preventDefault();
|
|
7073
|
-
videoRef.current.currentTime -= 10;
|
|
7074
|
-
}
|
|
7075
|
-
if (e.key === "ArrowRight" && videoRef.current) {
|
|
7076
|
-
e.preventDefault();
|
|
7077
|
-
videoRef.current.currentTime += 10;
|
|
7078
|
-
}
|
|
7079
|
-
if (e.key === "ArrowUp") {
|
|
7080
|
-
e.preventDefault();
|
|
7081
|
-
handleVolumeChange(Math.min(100, volume * 100 + 10));
|
|
7082
|
-
}
|
|
7083
|
-
if (e.key === "ArrowDown") {
|
|
7084
|
-
e.preventDefault();
|
|
7085
|
-
handleVolumeChange(Math.max(0, volume * 100 - 10));
|
|
7086
|
-
}
|
|
7087
|
-
if (e.key === "m" || e.key === "M") {
|
|
7088
|
-
e.preventDefault();
|
|
7089
|
-
toggleMute();
|
|
7090
|
-
}
|
|
7091
|
-
if (e.key === "f" || e.key === "F") {
|
|
7092
|
-
e.preventDefault();
|
|
7093
|
-
toggleFullscreen();
|
|
7094
|
-
}
|
|
7095
|
-
},
|
|
7301
|
+
onKeyDown: handleVideoKeyDown,
|
|
7096
7302
|
tabIndex: 0,
|
|
7097
7303
|
"aria-label": title ? `Video: ${title}` : "Video player",
|
|
7098
7304
|
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
@@ -7122,9 +7328,9 @@ var VideoPlayer = ({
|
|
|
7122
7328
|
{
|
|
7123
7329
|
className: cn(
|
|
7124
7330
|
"absolute top-0 left-0 right-0 p-4 bg-gradient-to-b from-black/70 to-transparent transition-opacity",
|
|
7125
|
-
|
|
7331
|
+
getTopControlsOpacity()
|
|
7126
7332
|
),
|
|
7127
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "
|
|
7333
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7128
7334
|
IconButton_default,
|
|
7129
7335
|
{
|
|
7130
7336
|
icon: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_phosphor_react18.ArrowsInSimple, { size: 24 }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_phosphor_react18.ArrowsOutSimple, { size: 24 }),
|
|
@@ -7140,29 +7346,18 @@ var VideoPlayer = ({
|
|
|
7140
7346
|
{
|
|
7141
7347
|
className: cn(
|
|
7142
7348
|
"absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/90 to-transparent transition-opacity",
|
|
7143
|
-
|
|
7349
|
+
getBottomControlsOpacity()
|
|
7144
7350
|
),
|
|
7145
7351
|
children: [
|
|
7146
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7147
|
-
|
|
7352
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7353
|
+
ProgressBar2,
|
|
7148
7354
|
{
|
|
7149
|
-
|
|
7150
|
-
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
onChange: (e) => {
|
|
7154
|
-
const newTime = parseFloat(e.target.value);
|
|
7155
|
-
if (videoRef.current) {
|
|
7156
|
-
videoRef.current.currentTime = newTime;
|
|
7157
|
-
}
|
|
7158
|
-
},
|
|
7159
|
-
className: "w-full h-1 bg-neutral-600 rounded-full appearance-none cursor-pointer slider:bg-primary-600 focus:outline-none focus:ring-2 focus:ring-primary-500",
|
|
7160
|
-
"aria-label": "Video progress",
|
|
7161
|
-
style: {
|
|
7162
|
-
background: `linear-gradient(to right, #2271C4 ${progressPercentage}%, #D5D4D4 ${progressPercentage}%)`
|
|
7163
|
-
}
|
|
7355
|
+
currentTime,
|
|
7356
|
+
duration,
|
|
7357
|
+
progressPercentage,
|
|
7358
|
+
onSeek: handleSeek
|
|
7164
7359
|
}
|
|
7165
|
-
)
|
|
7360
|
+
),
|
|
7166
7361
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center justify-between px-4 pb-4", children: [
|
|
7167
7362
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center gap-4", children: [
|
|
7168
7363
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
@@ -7174,32 +7369,15 @@ var VideoPlayer = ({
|
|
|
7174
7369
|
className: "!bg-transparent !text-white hover:!bg-white/20"
|
|
7175
7370
|
}
|
|
7176
7371
|
),
|
|
7177
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.
|
|
7178
|
-
|
|
7179
|
-
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
),
|
|
7187
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7188
|
-
"input",
|
|
7189
|
-
{
|
|
7190
|
-
type: "range",
|
|
7191
|
-
min: 0,
|
|
7192
|
-
max: 100,
|
|
7193
|
-
value: Math.round(volume * 100),
|
|
7194
|
-
onChange: (e) => handleVolumeChange(parseInt(e.target.value)),
|
|
7195
|
-
className: "w-20 h-1 bg-neutral-600 rounded-full appearance-none cursor-pointer focus:outline-none focus:ring-2 focus:ring-primary-500",
|
|
7196
|
-
"aria-label": "Volume control",
|
|
7197
|
-
style: {
|
|
7198
|
-
background: `linear-gradient(to right, #2271C4 ${volume * 100}%, #D5D4D4 ${volume * 100}%)`
|
|
7199
|
-
}
|
|
7200
|
-
}
|
|
7201
|
-
)
|
|
7202
|
-
] }),
|
|
7372
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7373
|
+
VolumeControls,
|
|
7374
|
+
{
|
|
7375
|
+
volume,
|
|
7376
|
+
isMuted,
|
|
7377
|
+
onVolumeChange: handleVolumeChange,
|
|
7378
|
+
onToggleMute: toggleMute
|
|
7379
|
+
}
|
|
7380
|
+
),
|
|
7203
7381
|
subtitles && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7204
7382
|
IconButton_default,
|
|
7205
7383
|
{
|
|
@@ -7218,29 +7396,15 @@ var VideoPlayer = ({
|
|
|
7218
7396
|
formatTime(duration)
|
|
7219
7397
|
] })
|
|
7220
7398
|
] }),
|
|
7221
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex items-center gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime36.
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
),
|
|
7231
|
-
showSpeedMenu && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "absolute bottom-12 right-0 bg-black/90 rounded-lg p-2 min-w-20", children: [0.5, 0.75, 1, 1.25, 1.5, 2].map((speed) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
7232
|
-
"button",
|
|
7233
|
-
{
|
|
7234
|
-
onClick: () => handleSpeedChange(speed),
|
|
7235
|
-
className: `block w-full text-left px-3 py-1 text-sm rounded hover:bg-white/20 transition-colors ${playbackRate === speed ? "text-primary-400" : "text-white"}`,
|
|
7236
|
-
children: [
|
|
7237
|
-
speed,
|
|
7238
|
-
"x"
|
|
7239
|
-
]
|
|
7240
|
-
},
|
|
7241
|
-
speed
|
|
7242
|
-
)) })
|
|
7243
|
-
] }) })
|
|
7399
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex items-center gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
7400
|
+
SpeedMenu,
|
|
7401
|
+
{
|
|
7402
|
+
showSpeedMenu,
|
|
7403
|
+
playbackRate,
|
|
7404
|
+
onToggleMenu: toggleSpeedMenu,
|
|
7405
|
+
onSpeedChange: handleSpeedChange
|
|
7406
|
+
}
|
|
7407
|
+
) })
|
|
7244
7408
|
] })
|
|
7245
7409
|
]
|
|
7246
7410
|
}
|