@optifye/dashboard-core 6.9.11 → 6.9.12
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/index.css +59 -0
- package/dist/index.js +650 -206
- package/dist/index.mjs +650 -206
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2925,8 +2925,8 @@ var AuthService = class {
|
|
|
2925
2925
|
"Authorization": `Bearer ${accessToken}`,
|
|
2926
2926
|
"Content-Type": "application/json"
|
|
2927
2927
|
},
|
|
2928
|
-
timeout:
|
|
2929
|
-
//
|
|
2928
|
+
timeout: 1e4,
|
|
2929
|
+
// 10 seconds
|
|
2930
2930
|
retries: 1,
|
|
2931
2931
|
silentErrors: false
|
|
2932
2932
|
// We want to know about auth errors
|
|
@@ -2963,8 +2963,8 @@ var AuthService = class {
|
|
|
2963
2963
|
"Authorization": `Bearer ${accessToken}`,
|
|
2964
2964
|
"Content-Type": "application/json"
|
|
2965
2965
|
},
|
|
2966
|
-
timeout:
|
|
2967
|
-
//
|
|
2966
|
+
timeout: 1e4,
|
|
2967
|
+
// 10 seconds
|
|
2968
2968
|
retries: 2,
|
|
2969
2969
|
// More retries for validation
|
|
2970
2970
|
silentErrors: true,
|
|
@@ -2996,8 +2996,8 @@ var AuthService = class {
|
|
|
2996
2996
|
"Authorization": `Bearer ${accessToken}`,
|
|
2997
2997
|
"Content-Type": "application/json"
|
|
2998
2998
|
},
|
|
2999
|
-
timeout:
|
|
3000
|
-
//
|
|
2999
|
+
timeout: 1e4,
|
|
3000
|
+
// 10 seconds
|
|
3001
3001
|
retries: 1,
|
|
3002
3002
|
silentErrors: false
|
|
3003
3003
|
}
|
|
@@ -10912,7 +10912,7 @@ function useDateFormatter() {
|
|
|
10912
10912
|
},
|
|
10913
10913
|
[defaultTimezone, defaultLocale, dateFormatOptions]
|
|
10914
10914
|
);
|
|
10915
|
-
const
|
|
10915
|
+
const formatTime4 = React23.useCallback(
|
|
10916
10916
|
(date, formatString) => {
|
|
10917
10917
|
const dateObj = typeof date === "string" ? dateFns.parseISO(date) : date;
|
|
10918
10918
|
if (!dateFns.isValid(dateObj)) return "Invalid Time";
|
|
@@ -10943,7 +10943,7 @@ function useDateFormatter() {
|
|
|
10943
10943
|
}, []);
|
|
10944
10944
|
return {
|
|
10945
10945
|
formatDate,
|
|
10946
|
-
formatTime:
|
|
10946
|
+
formatTime: formatTime4,
|
|
10947
10947
|
formatDateTime,
|
|
10948
10948
|
getNow,
|
|
10949
10949
|
timezone: defaultTimezone || "UTC",
|
|
@@ -23929,7 +23929,7 @@ var HourlyOutputChartComponent = ({
|
|
|
23929
23929
|
endHour = Math.floor(endDecimalHour) % 24;
|
|
23930
23930
|
endMinute = Math.round(endDecimalHour % 1 * 60);
|
|
23931
23931
|
}
|
|
23932
|
-
const
|
|
23932
|
+
const formatTime4 = (h, m) => {
|
|
23933
23933
|
const period = h >= 12 ? "PM" : "AM";
|
|
23934
23934
|
const hour12 = h === 0 ? 12 : h > 12 ? h - 12 : h;
|
|
23935
23935
|
if (m === 0) {
|
|
@@ -23937,7 +23937,7 @@ var HourlyOutputChartComponent = ({
|
|
|
23937
23937
|
}
|
|
23938
23938
|
return `${hour12}:${m.toString().padStart(2, "0")}${period}`;
|
|
23939
23939
|
};
|
|
23940
|
-
return `${
|
|
23940
|
+
return `${formatTime4(startHour, startMinute)}-${formatTime4(endHour, endMinute)}`;
|
|
23941
23941
|
}, [shiftStartTime.decimalHour, SHIFT_DURATION, shiftEndTime]);
|
|
23942
23942
|
const formatTimeRange = React23__namespace.default.useCallback((hourIndex) => {
|
|
23943
23943
|
const isLastHour = hourIndex === SHIFT_DURATION - 1;
|
|
@@ -23953,12 +23953,12 @@ var HourlyOutputChartComponent = ({
|
|
|
23953
23953
|
endHour = Math.floor(endDecimalHour) % 24;
|
|
23954
23954
|
endMinute = Math.round(endDecimalHour % 1 * 60);
|
|
23955
23955
|
}
|
|
23956
|
-
const
|
|
23956
|
+
const formatTime4 = (h, m) => {
|
|
23957
23957
|
const period = h >= 12 ? "PM" : "AM";
|
|
23958
23958
|
const hour12 = h === 0 ? 12 : h > 12 ? h - 12 : h;
|
|
23959
23959
|
return `${hour12}:${m.toString().padStart(2, "0")} ${period}`;
|
|
23960
23960
|
};
|
|
23961
|
-
return `${
|
|
23961
|
+
return `${formatTime4(startHour, startMinute)} - ${formatTime4(endHour, endMinute)}`;
|
|
23962
23962
|
}, [shiftStartTime.decimalHour, SHIFT_DURATION, shiftEndTime]);
|
|
23963
23963
|
const chartData = React23__namespace.default.useMemo(() => {
|
|
23964
23964
|
return Array.from({ length: SHIFT_DURATION }, (_, i) => {
|
|
@@ -25129,7 +25129,7 @@ var SOPComplianceChart = ({
|
|
|
25129
25129
|
}
|
|
25130
25130
|
};
|
|
25131
25131
|
}, [data, animateToNewData, mockData]);
|
|
25132
|
-
const
|
|
25132
|
+
const formatTime4 = (minuteIndex) => {
|
|
25133
25133
|
const totalMinutes = shiftStartHour * 60 + minuteIndex;
|
|
25134
25134
|
const hours = Math.floor(totalMinutes / 60) % 24;
|
|
25135
25135
|
const minutes = totalMinutes % 60;
|
|
@@ -25141,7 +25141,7 @@ var SOPComplianceChart = ({
|
|
|
25141
25141
|
const hasDataForMinute = index < animatedData.length - 10;
|
|
25142
25142
|
return {
|
|
25143
25143
|
minute: index,
|
|
25144
|
-
time:
|
|
25144
|
+
time: formatTime4(index),
|
|
25145
25145
|
compliance: hasDataForMinute ? animatedData[index] : null
|
|
25146
25146
|
};
|
|
25147
25147
|
});
|
|
@@ -25575,7 +25575,7 @@ var DateTimeDisplay = ({
|
|
|
25575
25575
|
const {
|
|
25576
25576
|
defaultTimezone
|
|
25577
25577
|
} = useDateTimeConfig();
|
|
25578
|
-
const { formatDate, formatTime:
|
|
25578
|
+
const { formatDate, formatTime: formatTime4 } = useDateFormatter();
|
|
25579
25579
|
const [now2, setNow] = React23.useState(() => getCurrentTimeInZone(defaultTimezone || "UTC"));
|
|
25580
25580
|
React23.useEffect(() => {
|
|
25581
25581
|
const timerId = setInterval(() => {
|
|
@@ -25587,7 +25587,7 @@ var DateTimeDisplay = ({
|
|
|
25587
25587
|
return null;
|
|
25588
25588
|
}
|
|
25589
25589
|
const formattedDate = showDate ? formatDate(now2) : "";
|
|
25590
|
-
const formattedTime = showTime ?
|
|
25590
|
+
const formattedTime = showTime ? formatTime4(now2) : "";
|
|
25591
25591
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx_default("flex items-center space-x-2 text-sm text-gray-700 dark:text-gray-300", className), children: [
|
|
25592
25592
|
showDate && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "date-display", "aria-label": `Current date: ${formattedDate}`, children: formattedDate }),
|
|
25593
25593
|
showDate && showTime && formattedDate && formattedTime && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "separator", "aria-hidden": "true", children: "|" }),
|
|
@@ -25751,7 +25751,7 @@ var BreakNotificationPopup = ({
|
|
|
25751
25751
|
const handlePrevious = () => {
|
|
25752
25752
|
setCurrentIndex((prev) => (prev - 1 + visibleBreaks.length) % visibleBreaks.length);
|
|
25753
25753
|
};
|
|
25754
|
-
const
|
|
25754
|
+
const formatTime4 = (minutes) => {
|
|
25755
25755
|
const hours = Math.floor(minutes / 60);
|
|
25756
25756
|
const mins = minutes % 60;
|
|
25757
25757
|
if (hours > 0) {
|
|
@@ -25825,9 +25825,9 @@ var BreakNotificationPopup = ({
|
|
|
25825
25825
|
formatTo12Hour(currentBreak.endTime)
|
|
25826
25826
|
] }),
|
|
25827
25827
|
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 mb-2", children: [
|
|
25828
|
-
|
|
25828
|
+
formatTime4(currentBreak.elapsedMinutes),
|
|
25829
25829
|
" elapsed of ",
|
|
25830
|
-
|
|
25830
|
+
formatTime4(currentBreak.duration),
|
|
25831
25831
|
" total"
|
|
25832
25832
|
] }),
|
|
25833
25833
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full bg-gray-200 rounded-full h-1.5", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -26131,64 +26131,208 @@ var getSeverityColor = (severity) => {
|
|
|
26131
26131
|
return "bg-gray-500";
|
|
26132
26132
|
}
|
|
26133
26133
|
};
|
|
26134
|
-
var
|
|
26135
|
-
|
|
26134
|
+
var formatTime2 = (seconds) => {
|
|
26135
|
+
if (!seconds || isNaN(seconds)) return "0:00";
|
|
26136
|
+
const h = Math.floor(seconds / 3600);
|
|
26137
|
+
const m = Math.floor(seconds % 3600 / 60);
|
|
26138
|
+
const s = Math.floor(seconds % 60);
|
|
26139
|
+
if (h > 0) {
|
|
26140
|
+
return `${h}:${m.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}`;
|
|
26141
|
+
}
|
|
26142
|
+
return `${m}:${s.toString().padStart(2, "0")}`;
|
|
26143
|
+
};
|
|
26144
|
+
var VideoControls = ({
|
|
26136
26145
|
isPlaying,
|
|
26137
|
-
|
|
26146
|
+
currentTime,
|
|
26147
|
+
duration,
|
|
26148
|
+
buffered,
|
|
26149
|
+
showControls,
|
|
26150
|
+
controlsPinned = false,
|
|
26151
|
+
onTogglePinControls,
|
|
26152
|
+
playbackRate = 1,
|
|
26153
|
+
onPlayPause,
|
|
26154
|
+
onSeek,
|
|
26155
|
+
onSeekStart,
|
|
26156
|
+
onSeekEnd,
|
|
26157
|
+
onToggleFullscreen,
|
|
26158
|
+
onPlaybackRateChange,
|
|
26159
|
+
className = ""
|
|
26138
26160
|
}) => {
|
|
26139
|
-
const [
|
|
26140
|
-
const [
|
|
26161
|
+
const [isDragging, setIsDragging] = React23.useState(false);
|
|
26162
|
+
const [dragTime, setDragTime] = React23.useState(0);
|
|
26163
|
+
const [isHoveringProgressBar, setIsHoveringProgressBar] = React23.useState(false);
|
|
26164
|
+
const [showSpeedMenu, setShowSpeedMenu] = React23.useState(false);
|
|
26165
|
+
const speedMenuRef = React23.useRef(null);
|
|
26166
|
+
const progressColor = "#4b5563";
|
|
26167
|
+
const controlsVisible = showControls || controlsPinned;
|
|
26168
|
+
const getPercentage = (current, total) => {
|
|
26169
|
+
if (!total || total === 0) return 0;
|
|
26170
|
+
return Math.min(Math.max(current / total * 100, 0), 100);
|
|
26171
|
+
};
|
|
26172
|
+
const handleSeekChange = (e) => {
|
|
26173
|
+
const newTime = parseFloat(e.target.value);
|
|
26174
|
+
setDragTime(newTime);
|
|
26175
|
+
onSeek(newTime);
|
|
26176
|
+
};
|
|
26177
|
+
const handleSeekStart = () => {
|
|
26178
|
+
setIsDragging(true);
|
|
26179
|
+
setDragTime(currentTime);
|
|
26180
|
+
onSeekStart?.();
|
|
26181
|
+
};
|
|
26182
|
+
const handleSeekEnd = () => {
|
|
26183
|
+
setIsDragging(false);
|
|
26184
|
+
onSeekEnd?.();
|
|
26185
|
+
};
|
|
26141
26186
|
React23.useEffect(() => {
|
|
26142
|
-
|
|
26143
|
-
|
|
26144
|
-
|
|
26145
|
-
|
|
26146
|
-
|
|
26147
|
-
|
|
26148
|
-
|
|
26149
|
-
|
|
26150
|
-
|
|
26151
|
-
|
|
26152
|
-
|
|
26153
|
-
|
|
26154
|
-
|
|
26155
|
-
|
|
26156
|
-
}
|
|
26157
|
-
}, [show, duration]);
|
|
26158
|
-
if (!isVisible) return null;
|
|
26159
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
26187
|
+
const handleClickOutside = (event) => {
|
|
26188
|
+
if (speedMenuRef.current && !speedMenuRef.current.contains(event.target)) {
|
|
26189
|
+
setShowSpeedMenu(false);
|
|
26190
|
+
}
|
|
26191
|
+
};
|
|
26192
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
26193
|
+
return () => {
|
|
26194
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
26195
|
+
};
|
|
26196
|
+
}, []);
|
|
26197
|
+
const displayTime = isDragging ? dragTime : currentTime;
|
|
26198
|
+
const progressPercent = getPercentage(displayTime, duration);
|
|
26199
|
+
const bufferedPercent = getPercentage(buffered, duration);
|
|
26200
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
26160
26201
|
"div",
|
|
26161
26202
|
{
|
|
26162
|
-
className:
|
|
26163
|
-
style: {
|
|
26164
|
-
|
|
26165
|
-
|
|
26166
|
-
|
|
26167
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-black/70 rounded-full p-6", children: isPlaying ? (
|
|
26168
|
-
// Play icon (triangle)
|
|
26169
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
26170
|
-
"svg",
|
|
26171
|
-
{
|
|
26172
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
26173
|
-
viewBox: "0 0 24 24",
|
|
26174
|
-
fill: "white",
|
|
26175
|
-
className: "w-16 h-16",
|
|
26176
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 5v14l11-7z" })
|
|
26177
|
-
}
|
|
26178
|
-
)
|
|
26179
|
-
) : (
|
|
26180
|
-
// Pause icon (two bars)
|
|
26181
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
26182
|
-
"svg",
|
|
26203
|
+
className: `absolute bottom-0 left-0 right-0 px-3 pb-3 pt-12 bg-gradient-to-t from-black/80 via-black/40 to-transparent transition-opacity duration-300 ${controlsVisible ? "opacity-100" : "opacity-0 pointer-events-none"} ${className}`,
|
|
26204
|
+
style: { touchAction: "none" },
|
|
26205
|
+
children: [
|
|
26206
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
26207
|
+
"div",
|
|
26183
26208
|
{
|
|
26184
|
-
|
|
26185
|
-
|
|
26186
|
-
|
|
26187
|
-
|
|
26188
|
-
|
|
26209
|
+
className: "relative h-1 mb-4 group cursor-pointer",
|
|
26210
|
+
onMouseEnter: () => setIsHoveringProgressBar(true),
|
|
26211
|
+
onMouseLeave: () => setIsHoveringProgressBar(false),
|
|
26212
|
+
children: [
|
|
26213
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-2 -bottom-2 left-0 right-0 z-20" }),
|
|
26214
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-0 left-0 right-0 bottom-0 bg-white/20 rounded-full overflow-hidden z-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
26215
|
+
"div",
|
|
26216
|
+
{
|
|
26217
|
+
className: "absolute top-0 left-0 bottom-0 bg-white/40 transition-all duration-200",
|
|
26218
|
+
style: { width: `${bufferedPercent}%` }
|
|
26219
|
+
}
|
|
26220
|
+
) }),
|
|
26221
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
26222
|
+
"div",
|
|
26223
|
+
{
|
|
26224
|
+
className: "absolute top-0 left-0 bottom-0 bg-[#007bff] transition-all duration-75 z-10",
|
|
26225
|
+
style: { width: `${progressPercent}%`, backgroundColor: progressColor },
|
|
26226
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
26227
|
+
"div",
|
|
26228
|
+
{
|
|
26229
|
+
className: `absolute right-0 top-1/2 -translate-y-1/2 translate-x-1/2 w-3 h-3 rounded-full shadow transform transition-transform duration-200 ${isHoveringProgressBar || isDragging ? "scale-100" : "scale-0"}`,
|
|
26230
|
+
style: { backgroundColor: progressColor }
|
|
26231
|
+
}
|
|
26232
|
+
)
|
|
26233
|
+
}
|
|
26234
|
+
),
|
|
26235
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
26236
|
+
"input",
|
|
26237
|
+
{
|
|
26238
|
+
type: "range",
|
|
26239
|
+
min: "0",
|
|
26240
|
+
max: duration || 100,
|
|
26241
|
+
step: "0.1",
|
|
26242
|
+
value: displayTime,
|
|
26243
|
+
onChange: handleSeekChange,
|
|
26244
|
+
onMouseDown: handleSeekStart,
|
|
26245
|
+
onMouseUp: handleSeekEnd,
|
|
26246
|
+
onTouchStart: handleSeekStart,
|
|
26247
|
+
onTouchEnd: handleSeekEnd,
|
|
26248
|
+
className: "absolute inset-0 w-full h-full opacity-0 cursor-pointer z-30 margin-0 padding-0"
|
|
26249
|
+
}
|
|
26250
|
+
)
|
|
26251
|
+
]
|
|
26189
26252
|
}
|
|
26190
|
-
)
|
|
26191
|
-
|
|
26253
|
+
),
|
|
26254
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-white", children: [
|
|
26255
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
|
|
26256
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
26257
|
+
"button",
|
|
26258
|
+
{
|
|
26259
|
+
onClick: (e) => {
|
|
26260
|
+
e.stopPropagation();
|
|
26261
|
+
onPlayPause();
|
|
26262
|
+
},
|
|
26263
|
+
className: "hover:text-[#007bff] transition-colors focus:outline-none",
|
|
26264
|
+
"aria-label": isPlaying ? "Pause" : "Play",
|
|
26265
|
+
children: isPlaying ? /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 4h4v16H6V4zm8 0h4v16h-4V4z" }) }) : /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 5v14l11-7z" }) })
|
|
26266
|
+
}
|
|
26267
|
+
),
|
|
26268
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs font-medium font-sans", children: [
|
|
26269
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatTime2(displayTime) }),
|
|
26270
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "mx-1 text-white/70", children: "/" }),
|
|
26271
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-white/70", children: formatTime2(duration) })
|
|
26272
|
+
] })
|
|
26273
|
+
] }),
|
|
26274
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
|
|
26275
|
+
onTogglePinControls && /* @__PURE__ */ jsxRuntime.jsx(
|
|
26276
|
+
"button",
|
|
26277
|
+
{
|
|
26278
|
+
onClick: (e) => {
|
|
26279
|
+
e.stopPropagation();
|
|
26280
|
+
onTogglePinControls();
|
|
26281
|
+
},
|
|
26282
|
+
className: `transition-colors focus:outline-none ${controlsPinned ? "text-[#007bff]" : "hover:text-[#007bff]"}`,
|
|
26283
|
+
"aria-label": controlsPinned ? "Unpin controls" : "Pin controls",
|
|
26284
|
+
title: controlsPinned ? "Unpin controls" : "Pin controls",
|
|
26285
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: controlsPinned ? /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 3h6l-1 7h3v2h-4.5l-.5 4.5-2 1L10 12H6v-2h3z" }) : /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M9 3h6l-1 7h3v2h-4v5l-2 1-1-6H6v-2h3z" }) })
|
|
26286
|
+
}
|
|
26287
|
+
),
|
|
26288
|
+
onPlaybackRateChange && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", ref: speedMenuRef, children: [
|
|
26289
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
26290
|
+
"button",
|
|
26291
|
+
{
|
|
26292
|
+
onClick: (e) => {
|
|
26293
|
+
e.stopPropagation();
|
|
26294
|
+
setShowSpeedMenu(!showSpeedMenu);
|
|
26295
|
+
},
|
|
26296
|
+
className: "text-xs font-medium hover:text-[#007bff] transition-colors focus:outline-none min-w-[32px]",
|
|
26297
|
+
"aria-label": "Playback Speed",
|
|
26298
|
+
children: [
|
|
26299
|
+
playbackRate,
|
|
26300
|
+
"x"
|
|
26301
|
+
]
|
|
26302
|
+
}
|
|
26303
|
+
),
|
|
26304
|
+
showSpeedMenu && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-full right-0 mb-2 bg-black/90 text-white rounded shadow-lg overflow-hidden z-50 min-w-[80px]", children: [0.5, 1, 1.5, 2, 2.5, 3, 4, 5].map((rate) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
26305
|
+
"button",
|
|
26306
|
+
{
|
|
26307
|
+
onClick: (e) => {
|
|
26308
|
+
e.stopPropagation();
|
|
26309
|
+
onPlaybackRateChange(rate);
|
|
26310
|
+
setShowSpeedMenu(false);
|
|
26311
|
+
},
|
|
26312
|
+
className: `block w-full text-left px-4 py-2 text-xs hover:bg-white/20 transition-colors ${playbackRate === rate ? "text-[#007bff] font-bold" : ""}`,
|
|
26313
|
+
children: [
|
|
26314
|
+
rate,
|
|
26315
|
+
"x"
|
|
26316
|
+
]
|
|
26317
|
+
},
|
|
26318
|
+
rate
|
|
26319
|
+
)) })
|
|
26320
|
+
] }),
|
|
26321
|
+
onToggleFullscreen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
26322
|
+
"button",
|
|
26323
|
+
{
|
|
26324
|
+
onClick: (e) => {
|
|
26325
|
+
e.stopPropagation();
|
|
26326
|
+
onToggleFullscreen();
|
|
26327
|
+
},
|
|
26328
|
+
className: "hover:text-[#007bff] transition-colors focus:outline-none",
|
|
26329
|
+
"aria-label": "Toggle Fullscreen",
|
|
26330
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z" }) })
|
|
26331
|
+
}
|
|
26332
|
+
)
|
|
26333
|
+
] })
|
|
26334
|
+
] })
|
|
26335
|
+
]
|
|
26192
26336
|
}
|
|
26193
26337
|
);
|
|
26194
26338
|
};
|
|
@@ -26316,9 +26460,15 @@ var HlsVideoPlayer = React23.forwardRef(({
|
|
|
26316
26460
|
const blobUrlRef = React23.useRef(null);
|
|
26317
26461
|
const [isReady, setIsReady] = React23.useState(false);
|
|
26318
26462
|
const [isLoading, setIsLoading] = React23.useState(true);
|
|
26319
|
-
const [
|
|
26320
|
-
const [
|
|
26321
|
-
const
|
|
26463
|
+
const [showControls, setShowControls] = React23.useState(true);
|
|
26464
|
+
const [controlsPinned, setControlsPinned] = React23.useState(false);
|
|
26465
|
+
const [isPlaying, setIsPlaying] = React23.useState(false);
|
|
26466
|
+
const [currentTime, setCurrentTime] = React23.useState(0);
|
|
26467
|
+
const [duration, setDuration] = React23.useState(0);
|
|
26468
|
+
const [buffered, setBuffered] = React23.useState(0);
|
|
26469
|
+
const [playbackRate, setPlaybackRate] = React23.useState(1);
|
|
26470
|
+
const userSeekingRef = React23.useRef(false);
|
|
26471
|
+
const controlsTimeoutRef = React23.useRef(null);
|
|
26322
26472
|
const eventCallbacksRef = React23.useRef({
|
|
26323
26473
|
onReady,
|
|
26324
26474
|
onPlay,
|
|
@@ -26497,8 +26647,6 @@ var HlsVideoPlayer = React23.forwardRef(({
|
|
|
26497
26647
|
}
|
|
26498
26648
|
});
|
|
26499
26649
|
hls.on(Hls3.Events.FRAG_LOADING, () => {
|
|
26500
|
-
setIsLoading(true);
|
|
26501
|
-
eventCallbacksRef.current.onLoadingChange?.(true);
|
|
26502
26650
|
});
|
|
26503
26651
|
hls.on(Hls3.Events.FRAG_LOADED, () => {
|
|
26504
26652
|
setIsLoading(false);
|
|
@@ -26552,25 +26700,52 @@ var HlsVideoPlayer = React23.forwardRef(({
|
|
|
26552
26700
|
const handleCanPlay = () => {
|
|
26553
26701
|
if (!hlsRef.current) {
|
|
26554
26702
|
setIsReady(true);
|
|
26555
|
-
onReady?.(player);
|
|
26556
26703
|
}
|
|
26704
|
+
setIsLoading(false);
|
|
26705
|
+
eventCallbacksRef.current.onLoadingChange?.(false);
|
|
26706
|
+
onReady?.(player);
|
|
26707
|
+
};
|
|
26708
|
+
const handlePlay = () => {
|
|
26709
|
+
setIsPlaying(true);
|
|
26710
|
+
eventCallbacksRef.current.onPlay?.(player);
|
|
26711
|
+
};
|
|
26712
|
+
const handlePause = () => {
|
|
26713
|
+
if (userSeekingRef.current && videoRef.current) {
|
|
26714
|
+
videoRef.current.play().catch((err) => console.warn("Auto-resume after seek pause failed:", err));
|
|
26715
|
+
return;
|
|
26716
|
+
}
|
|
26717
|
+
setIsPlaying(false);
|
|
26718
|
+
eventCallbacksRef.current.onPause?.(player);
|
|
26557
26719
|
};
|
|
26558
|
-
const handlePlay = () => eventCallbacksRef.current.onPlay?.(player);
|
|
26559
|
-
const handlePause = () => eventCallbacksRef.current.onPause?.(player);
|
|
26560
26720
|
const handlePlaying = () => {
|
|
26561
26721
|
setIsLoading(false);
|
|
26722
|
+
setIsPlaying(true);
|
|
26562
26723
|
eventCallbacksRef.current.onLoadingChange?.(false);
|
|
26563
26724
|
eventCallbacksRef.current.onPlaying?.(player);
|
|
26564
26725
|
};
|
|
26565
26726
|
const handleTimeUpdate = () => {
|
|
26566
26727
|
const currentTime2 = video.currentTime || 0;
|
|
26728
|
+
setCurrentTime(currentTime2);
|
|
26729
|
+
if (video.buffered.length > 0) {
|
|
26730
|
+
for (let i = 0; i < video.buffered.length; i++) {
|
|
26731
|
+
if (video.buffered.start(i) <= currentTime2 && video.buffered.end(i) >= currentTime2) {
|
|
26732
|
+
setBuffered(video.buffered.end(i));
|
|
26733
|
+
break;
|
|
26734
|
+
}
|
|
26735
|
+
}
|
|
26736
|
+
}
|
|
26567
26737
|
eventCallbacksRef.current.onTimeUpdate?.(player, currentTime2);
|
|
26568
26738
|
};
|
|
26569
26739
|
const handleDurationChange = () => {
|
|
26570
26740
|
const duration2 = video.duration || 0;
|
|
26741
|
+
setDuration(duration2);
|
|
26571
26742
|
eventCallbacksRef.current.onDurationChange?.(player, duration2);
|
|
26572
26743
|
};
|
|
26573
|
-
const handleEnded = () =>
|
|
26744
|
+
const handleEnded = () => {
|
|
26745
|
+
setIsPlaying(false);
|
|
26746
|
+
userSeekingRef.current = false;
|
|
26747
|
+
eventCallbacksRef.current.onEnded?.(player);
|
|
26748
|
+
};
|
|
26574
26749
|
const handleLoadStart = () => {
|
|
26575
26750
|
setIsLoading(true);
|
|
26576
26751
|
eventCallbacksRef.current.onLoadingChange?.(true);
|
|
@@ -26586,8 +26761,19 @@ var HlsVideoPlayer = React23.forwardRef(({
|
|
|
26586
26761
|
setIsLoading(true);
|
|
26587
26762
|
eventCallbacksRef.current.onLoadingChange?.(true);
|
|
26588
26763
|
};
|
|
26589
|
-
const handleSeeking = () =>
|
|
26590
|
-
|
|
26764
|
+
const handleSeeking = () => {
|
|
26765
|
+
userSeekingRef.current = true;
|
|
26766
|
+
eventCallbacksRef.current.onSeeking?.(player);
|
|
26767
|
+
};
|
|
26768
|
+
const handleSeeked = () => {
|
|
26769
|
+
setIsLoading(false);
|
|
26770
|
+
eventCallbacksRef.current.onLoadingChange?.(false);
|
|
26771
|
+
if (videoRef.current) {
|
|
26772
|
+
videoRef.current.play().catch((err) => console.warn("Resume playback after seek failed:", err));
|
|
26773
|
+
}
|
|
26774
|
+
userSeekingRef.current = false;
|
|
26775
|
+
eventCallbacksRef.current.onSeeked?.(player);
|
|
26776
|
+
};
|
|
26591
26777
|
const handleError = () => {
|
|
26592
26778
|
const error = video.error;
|
|
26593
26779
|
if (error) {
|
|
@@ -26600,6 +26786,10 @@ var HlsVideoPlayer = React23.forwardRef(({
|
|
|
26600
26786
|
eventCallbacksRef.current.onError?.(player, errorInfo);
|
|
26601
26787
|
}
|
|
26602
26788
|
};
|
|
26789
|
+
const handlePlaybackRateChange2 = (e) => {
|
|
26790
|
+
const target = e.target;
|
|
26791
|
+
setPlaybackRate(target.playbackRate);
|
|
26792
|
+
};
|
|
26603
26793
|
video.addEventListener("canplay", handleCanPlay);
|
|
26604
26794
|
video.addEventListener("play", handlePlay);
|
|
26605
26795
|
video.addEventListener("pause", handlePause);
|
|
@@ -26614,6 +26804,7 @@ var HlsVideoPlayer = React23.forwardRef(({
|
|
|
26614
26804
|
video.addEventListener("seeking", handleSeeking);
|
|
26615
26805
|
video.addEventListener("seeked", handleSeeked);
|
|
26616
26806
|
video.addEventListener("error", handleError);
|
|
26807
|
+
video.addEventListener("ratechange", handlePlaybackRateChange2);
|
|
26617
26808
|
return () => {
|
|
26618
26809
|
video.removeEventListener("canplay", handleCanPlay);
|
|
26619
26810
|
video.removeEventListener("play", handlePlay);
|
|
@@ -26629,6 +26820,7 @@ var HlsVideoPlayer = React23.forwardRef(({
|
|
|
26629
26820
|
video.removeEventListener("seeking", handleSeeking);
|
|
26630
26821
|
video.removeEventListener("seeked", handleSeeked);
|
|
26631
26822
|
video.removeEventListener("error", handleError);
|
|
26823
|
+
video.removeEventListener("ratechange", handlePlaybackRateChange2);
|
|
26632
26824
|
};
|
|
26633
26825
|
}, [
|
|
26634
26826
|
src,
|
|
@@ -26657,20 +26849,46 @@ var HlsVideoPlayer = React23.forwardRef(({
|
|
|
26657
26849
|
}
|
|
26658
26850
|
}
|
|
26659
26851
|
}, [autoplay]);
|
|
26852
|
+
const resetControlsTimeout = React23.useCallback(() => {
|
|
26853
|
+
if (controlsPinned) {
|
|
26854
|
+
setShowControls(true);
|
|
26855
|
+
return;
|
|
26856
|
+
}
|
|
26857
|
+
setShowControls(true);
|
|
26858
|
+
if (controlsTimeoutRef.current) {
|
|
26859
|
+
clearTimeout(controlsTimeoutRef.current);
|
|
26860
|
+
}
|
|
26861
|
+
if (isPlaying) {
|
|
26862
|
+
controlsTimeoutRef.current = setTimeout(() => {
|
|
26863
|
+
setShowControls(false);
|
|
26864
|
+
}, 3e3);
|
|
26865
|
+
}
|
|
26866
|
+
}, [isPlaying, controlsPinned]);
|
|
26867
|
+
const handleMouseMove = React23.useCallback(() => {
|
|
26868
|
+
resetControlsTimeout();
|
|
26869
|
+
}, [resetControlsTimeout]);
|
|
26870
|
+
React23.useEffect(() => {
|
|
26871
|
+
resetControlsTimeout();
|
|
26872
|
+
return () => {
|
|
26873
|
+
if (controlsTimeoutRef.current) {
|
|
26874
|
+
clearTimeout(controlsTimeoutRef.current);
|
|
26875
|
+
}
|
|
26876
|
+
};
|
|
26877
|
+
}, [isPlaying, resetControlsTimeout]);
|
|
26660
26878
|
const play = React23.useCallback(() => {
|
|
26661
26879
|
return videoRef.current?.play();
|
|
26662
26880
|
}, []);
|
|
26663
26881
|
const pause = React23.useCallback(() => {
|
|
26664
26882
|
videoRef.current?.pause();
|
|
26665
26883
|
}, []);
|
|
26666
|
-
const
|
|
26884
|
+
const currentTimeProp = React23.useCallback((time2) => {
|
|
26667
26885
|
if (time2 !== void 0 && videoRef.current) {
|
|
26668
26886
|
videoRef.current.currentTime = time2;
|
|
26669
26887
|
return time2;
|
|
26670
26888
|
}
|
|
26671
26889
|
return videoRef.current?.currentTime || 0;
|
|
26672
26890
|
}, []);
|
|
26673
|
-
const
|
|
26891
|
+
const durationProp = React23.useCallback(() => {
|
|
26674
26892
|
return videoRef.current?.duration || 0;
|
|
26675
26893
|
}, []);
|
|
26676
26894
|
const paused = React23.useCallback(() => {
|
|
@@ -26683,95 +26901,144 @@ var HlsVideoPlayer = React23.forwardRef(({
|
|
|
26683
26901
|
}
|
|
26684
26902
|
return videoRef.current?.muted ?? false;
|
|
26685
26903
|
}, []);
|
|
26686
|
-
const
|
|
26904
|
+
const volumeProp = React23.useCallback((level) => {
|
|
26687
26905
|
if (level !== void 0 && videoRef.current) {
|
|
26688
26906
|
videoRef.current.volume = level;
|
|
26689
26907
|
return level;
|
|
26690
26908
|
}
|
|
26691
26909
|
return videoRef.current?.volume ?? 1;
|
|
26692
26910
|
}, []);
|
|
26693
|
-
const
|
|
26911
|
+
const playbackRateProp = React23.useCallback((rate) => {
|
|
26694
26912
|
if (rate !== void 0 && videoRef.current) {
|
|
26695
26913
|
videoRef.current.playbackRate = rate;
|
|
26696
26914
|
return rate;
|
|
26697
26915
|
}
|
|
26698
26916
|
return videoRef.current?.playbackRate ?? 1;
|
|
26699
26917
|
}, []);
|
|
26918
|
+
const handleTogglePlay = React23.useCallback(() => {
|
|
26919
|
+
if (videoRef.current) {
|
|
26920
|
+
if (videoRef.current.paused) {
|
|
26921
|
+
videoRef.current.play();
|
|
26922
|
+
} else {
|
|
26923
|
+
videoRef.current.pause();
|
|
26924
|
+
}
|
|
26925
|
+
}
|
|
26926
|
+
}, []);
|
|
26927
|
+
const handleSeek = React23.useCallback((time2) => {
|
|
26928
|
+
if (videoRef.current) {
|
|
26929
|
+
videoRef.current.currentTime = time2;
|
|
26930
|
+
videoRef.current.play().catch((err) => console.warn("Resume playback failed during seek:", err));
|
|
26931
|
+
}
|
|
26932
|
+
}, []);
|
|
26933
|
+
const handleSeekStart = React23.useCallback(() => {
|
|
26934
|
+
userSeekingRef.current = true;
|
|
26935
|
+
}, []);
|
|
26936
|
+
const handleSeekEnd = React23.useCallback(() => {
|
|
26937
|
+
if (videoRef.current) {
|
|
26938
|
+
videoRef.current.play().catch((err) => console.warn("Resume playback failed after seek:", err));
|
|
26939
|
+
}
|
|
26940
|
+
}, []);
|
|
26941
|
+
const handlePlaybackRateChange = React23.useCallback((rate) => {
|
|
26942
|
+
if (videoRef.current) {
|
|
26943
|
+
videoRef.current.playbackRate = rate;
|
|
26944
|
+
}
|
|
26945
|
+
}, []);
|
|
26946
|
+
const handleToggleFullscreen = React23.useCallback(() => {
|
|
26947
|
+
if (videoContainerRef.current) {
|
|
26948
|
+
if (!document.fullscreenElement) {
|
|
26949
|
+
videoContainerRef.current.requestFullscreen();
|
|
26950
|
+
} else {
|
|
26951
|
+
document.exitFullscreen();
|
|
26952
|
+
}
|
|
26953
|
+
}
|
|
26954
|
+
}, []);
|
|
26700
26955
|
React23.useImperativeHandle(ref, () => ({
|
|
26701
26956
|
hls: hlsRef.current,
|
|
26702
26957
|
video: videoRef.current,
|
|
26703
26958
|
play,
|
|
26704
26959
|
pause,
|
|
26705
|
-
currentTime,
|
|
26706
|
-
duration,
|
|
26960
|
+
currentTime: currentTimeProp,
|
|
26961
|
+
duration: durationProp,
|
|
26707
26962
|
paused,
|
|
26708
26963
|
mute,
|
|
26709
|
-
volume,
|
|
26710
|
-
playbackRate,
|
|
26964
|
+
volume: volumeProp,
|
|
26965
|
+
playbackRate: playbackRateProp,
|
|
26711
26966
|
dispose,
|
|
26712
26967
|
isReady,
|
|
26713
26968
|
// For backward compatibility with Video.js API
|
|
26714
26969
|
player: playerLikeObject()
|
|
26715
|
-
}), [play, pause,
|
|
26716
|
-
const
|
|
26717
|
-
if (!onClick
|
|
26718
|
-
|
|
26719
|
-
|
|
26720
|
-
|
|
26721
|
-
|
|
26722
|
-
|
|
26723
|
-
|
|
26724
|
-
|
|
26725
|
-
|
|
26726
|
-
|
|
26727
|
-
|
|
26728
|
-
|
|
26729
|
-
|
|
26730
|
-
|
|
26731
|
-
|
|
26732
|
-
|
|
26733
|
-
|
|
26734
|
-
"video",
|
|
26970
|
+
}), [play, pause, currentTimeProp, durationProp, paused, mute, volumeProp, playbackRateProp, dispose, isReady, playerLikeObject]);
|
|
26971
|
+
const handleContainerClick = React23.useCallback(() => {
|
|
26972
|
+
if (!onClick && !controls) {
|
|
26973
|
+
handleTogglePlay();
|
|
26974
|
+
}
|
|
26975
|
+
if (onClick) {
|
|
26976
|
+
onClick();
|
|
26977
|
+
}
|
|
26978
|
+
}, [onClick, controls, handleTogglePlay]);
|
|
26979
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
26980
|
+
"div",
|
|
26981
|
+
{
|
|
26982
|
+
className: `hls-video-player-wrapper ${className} group`,
|
|
26983
|
+
style: { position: "relative", width: "100%", height: "100%" },
|
|
26984
|
+
onMouseMove: handleMouseMove,
|
|
26985
|
+
onMouseLeave: () => isPlaying && !controlsPinned && setShowControls(false),
|
|
26986
|
+
children: [
|
|
26987
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
26988
|
+
"div",
|
|
26735
26989
|
{
|
|
26736
|
-
|
|
26737
|
-
|
|
26738
|
-
|
|
26739
|
-
|
|
26740
|
-
|
|
26741
|
-
|
|
26742
|
-
|
|
26743
|
-
|
|
26744
|
-
|
|
26990
|
+
className: "hls-video-player-container",
|
|
26991
|
+
ref: videoContainerRef,
|
|
26992
|
+
onClick: handleContainerClick,
|
|
26993
|
+
children: [
|
|
26994
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
26995
|
+
"video",
|
|
26996
|
+
{
|
|
26997
|
+
ref: videoRef,
|
|
26998
|
+
className: "hls-video-element",
|
|
26999
|
+
poster,
|
|
27000
|
+
controls: false,
|
|
27001
|
+
loop,
|
|
27002
|
+
muted,
|
|
27003
|
+
playsInline,
|
|
27004
|
+
autoPlay: autoplay,
|
|
27005
|
+
preload: "metadata"
|
|
27006
|
+
}
|
|
27007
|
+
),
|
|
27008
|
+
controls && /* @__PURE__ */ jsxRuntime.jsx(
|
|
27009
|
+
VideoControls,
|
|
27010
|
+
{
|
|
27011
|
+
isPlaying,
|
|
27012
|
+
currentTime,
|
|
27013
|
+
duration,
|
|
27014
|
+
buffered,
|
|
27015
|
+
showControls: controlsPinned || showControls || !isPlaying,
|
|
27016
|
+
controlsPinned,
|
|
27017
|
+
playbackRate,
|
|
27018
|
+
onPlayPause: handleTogglePlay,
|
|
27019
|
+
onSeek: handleSeek,
|
|
27020
|
+
onSeekStart: handleSeekStart,
|
|
27021
|
+
onSeekEnd: handleSeekEnd,
|
|
27022
|
+
onPlaybackRateChange: handlePlaybackRateChange,
|
|
27023
|
+
onTogglePinControls: () => setControlsPinned((prev) => {
|
|
27024
|
+
const next = !prev;
|
|
27025
|
+
if (next) {
|
|
27026
|
+
setShowControls(true);
|
|
27027
|
+
} else {
|
|
27028
|
+
resetControlsTimeout();
|
|
27029
|
+
}
|
|
27030
|
+
return next;
|
|
27031
|
+
}),
|
|
27032
|
+
onToggleFullscreen: handleToggleFullscreen
|
|
27033
|
+
}
|
|
27034
|
+
)
|
|
27035
|
+
]
|
|
26745
27036
|
}
|
|
26746
|
-
)
|
|
26747
|
-
|
|
26748
|
-
|
|
26749
|
-
|
|
26750
|
-
|
|
26751
|
-
"div",
|
|
26752
|
-
{
|
|
26753
|
-
onClick: handleClickWithIndicator,
|
|
26754
|
-
style: {
|
|
26755
|
-
position: "absolute",
|
|
26756
|
-
top: 0,
|
|
26757
|
-
left: 0,
|
|
26758
|
-
right: 0,
|
|
26759
|
-
bottom: 0,
|
|
26760
|
-
zIndex: 1,
|
|
26761
|
-
cursor: "pointer"
|
|
26762
|
-
},
|
|
26763
|
-
"aria-label": "Click to play/pause"
|
|
26764
|
-
}
|
|
26765
|
-
),
|
|
26766
|
-
onClick && !controls && /* @__PURE__ */ jsxRuntime.jsx(
|
|
26767
|
-
PlayPauseIndicator,
|
|
26768
|
-
{
|
|
26769
|
-
show: showIndicator,
|
|
26770
|
-
isPlaying: indicatorIsPlaying
|
|
26771
|
-
},
|
|
26772
|
-
indicatorKeyRef.current
|
|
26773
|
-
)
|
|
26774
|
-
] });
|
|
27037
|
+
),
|
|
27038
|
+
isLoading && !externalLoadingControl && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hls-video-player-loading", children: /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) })
|
|
27039
|
+
]
|
|
27040
|
+
}
|
|
27041
|
+
);
|
|
26775
27042
|
});
|
|
26776
27043
|
HlsVideoPlayer.displayName = "HlsVideoPlayer";
|
|
26777
27044
|
var VideoPlayer = HlsVideoPlayer;
|
|
@@ -26779,6 +27046,7 @@ var CroppedHlsVideoPlayer = React23.forwardRef(({
|
|
|
26779
27046
|
crop,
|
|
26780
27047
|
debug = false,
|
|
26781
27048
|
onClick,
|
|
27049
|
+
controls = true,
|
|
26782
27050
|
...videoProps
|
|
26783
27051
|
}, ref) => {
|
|
26784
27052
|
const {
|
|
@@ -26800,9 +27068,15 @@ var CroppedHlsVideoPlayer = React23.forwardRef(({
|
|
|
26800
27068
|
const [isVideoReady, setIsVideoReady] = React23.useState(false);
|
|
26801
27069
|
const [canvasDimensions, setCanvasDimensions] = React23.useState({ width: 0, height: 0 });
|
|
26802
27070
|
const [isProcessing, setIsProcessing] = React23.useState(false);
|
|
26803
|
-
const [
|
|
26804
|
-
const [
|
|
26805
|
-
const
|
|
27071
|
+
const [showControls, setShowControls] = React23.useState(true);
|
|
27072
|
+
const [isPlaying, setIsPlaying] = React23.useState(false);
|
|
27073
|
+
const [currentTime, setCurrentTime] = React23.useState(0);
|
|
27074
|
+
const [duration, setDuration] = React23.useState(0);
|
|
27075
|
+
const [buffered, setBuffered] = React23.useState(0);
|
|
27076
|
+
const [playbackRate, setPlaybackRate] = React23.useState(1);
|
|
27077
|
+
const controlsTimeoutRef = React23.useRef(null);
|
|
27078
|
+
const userSeekingRef = React23.useRef(false);
|
|
27079
|
+
const [controlsPinned, setControlsPinned] = React23.useState(false);
|
|
26806
27080
|
const stopCanvasRendering = React23.useCallback(() => {
|
|
26807
27081
|
if (animationFrameRef.current) {
|
|
26808
27082
|
cancelAnimationFrame(animationFrameRef.current);
|
|
@@ -26887,7 +27161,7 @@ var CroppedHlsVideoPlayer = React23.forwardRef(({
|
|
|
26887
27161
|
const canvas = canvasRef.current;
|
|
26888
27162
|
const video = videoElementRef.current;
|
|
26889
27163
|
const ctx = canvas.getContext("2d");
|
|
26890
|
-
if (!ctx || video.
|
|
27164
|
+
if (!ctx || video.readyState < 2) {
|
|
26891
27165
|
return;
|
|
26892
27166
|
}
|
|
26893
27167
|
const videoWidth = video.videoWidth;
|
|
@@ -26914,7 +27188,9 @@ var CroppedHlsVideoPlayer = React23.forwardRef(({
|
|
|
26914
27188
|
canvas.height
|
|
26915
27189
|
// Destination (full canvas)
|
|
26916
27190
|
);
|
|
26917
|
-
|
|
27191
|
+
if (!video.paused && !video.ended) {
|
|
27192
|
+
animationFrameRef.current = requestAnimationFrame(renderFrameToCanvas);
|
|
27193
|
+
}
|
|
26918
27194
|
}, [crop]);
|
|
26919
27195
|
const handleVideoReady = React23.useCallback((player) => {
|
|
26920
27196
|
console.log("[CroppedHlsVideoPlayer] Video player ready");
|
|
@@ -26922,11 +27198,15 @@ var CroppedHlsVideoPlayer = React23.forwardRef(({
|
|
|
26922
27198
|
if (videoEl) {
|
|
26923
27199
|
videoElementRef.current = videoEl;
|
|
26924
27200
|
setIsVideoReady(true);
|
|
27201
|
+
if (videoEl.readyState >= 2) {
|
|
27202
|
+
renderFrameToCanvas();
|
|
27203
|
+
}
|
|
26925
27204
|
}
|
|
26926
27205
|
onReadyProp?.(player);
|
|
26927
|
-
}, [onReadyProp]);
|
|
27206
|
+
}, [onReadyProp, renderFrameToCanvas]);
|
|
26928
27207
|
const handleVideoPlay = React23.useCallback((player) => {
|
|
26929
27208
|
console.log("[CroppedHlsVideoPlayer] Video playing, starting canvas rendering");
|
|
27209
|
+
setIsPlaying(true);
|
|
26930
27210
|
if (crop && canvasRef.current) {
|
|
26931
27211
|
setIsProcessing(true);
|
|
26932
27212
|
renderFrameToCanvas();
|
|
@@ -26934,43 +27214,40 @@ var CroppedHlsVideoPlayer = React23.forwardRef(({
|
|
|
26934
27214
|
onPlayProp?.(player);
|
|
26935
27215
|
}, [crop, renderFrameToCanvas, onPlayProp]);
|
|
26936
27216
|
const handleVideoPause = React23.useCallback((player) => {
|
|
26937
|
-
console.log("[CroppedHlsVideoPlayer] Video paused, stopping canvas rendering
|
|
27217
|
+
console.log("[CroppedHlsVideoPlayer] Video paused, stopping canvas rendering (keeping last frame)");
|
|
27218
|
+
if (userSeekingRef.current && hiddenVideoRef.current) {
|
|
27219
|
+
hiddenVideoRef.current.play()?.catch(() => {
|
|
27220
|
+
});
|
|
27221
|
+
return;
|
|
27222
|
+
}
|
|
26938
27223
|
stopCanvasRendering();
|
|
26939
27224
|
setIsProcessing(false);
|
|
26940
|
-
|
|
26941
|
-
|
|
26942
|
-
if (ctx) {
|
|
26943
|
-
ctx.clearRect(0, 0, canvasRef.current.width, canvasRef.current.height);
|
|
26944
|
-
ctx.fillStyle = "black";
|
|
26945
|
-
ctx.fillRect(0, 0, canvasRef.current.width, canvasRef.current.height);
|
|
26946
|
-
}
|
|
26947
|
-
}
|
|
27225
|
+
setIsPlaying(false);
|
|
27226
|
+
renderFrameToCanvas();
|
|
26948
27227
|
onPauseProp?.(player);
|
|
26949
|
-
}, [stopCanvasRendering, onPauseProp]);
|
|
27228
|
+
}, [stopCanvasRendering, onPauseProp, renderFrameToCanvas]);
|
|
26950
27229
|
const handleVideoEnded = React23.useCallback((player) => {
|
|
26951
|
-
console.log("[CroppedHlsVideoPlayer] Video ended,
|
|
27230
|
+
console.log("[CroppedHlsVideoPlayer] Video ended, stopping canvas rendering (keeping last frame)");
|
|
26952
27231
|
stopCanvasRendering();
|
|
26953
27232
|
setIsProcessing(false);
|
|
26954
|
-
|
|
26955
|
-
|
|
26956
|
-
if (ctx) {
|
|
26957
|
-
ctx.clearRect(0, 0, canvasRef.current.width, canvasRef.current.height);
|
|
26958
|
-
ctx.fillStyle = "black";
|
|
26959
|
-
ctx.fillRect(0, 0, canvasRef.current.width, canvasRef.current.height);
|
|
26960
|
-
}
|
|
26961
|
-
}
|
|
27233
|
+
setIsPlaying(false);
|
|
27234
|
+
userSeekingRef.current = false;
|
|
26962
27235
|
onEndedProp?.(player);
|
|
26963
27236
|
}, [stopCanvasRendering, onEndedProp]);
|
|
26964
27237
|
const handleSeeking = React23.useCallback((player) => {
|
|
26965
27238
|
console.log("[CroppedHlsVideoPlayer] Video seeking");
|
|
26966
|
-
|
|
27239
|
+
userSeekingRef.current = true;
|
|
27240
|
+
if (crop) {
|
|
26967
27241
|
renderFrameToCanvas();
|
|
26968
27242
|
}
|
|
26969
27243
|
onSeekingProp?.(player);
|
|
26970
27244
|
}, [crop, renderFrameToCanvas, onSeekingProp]);
|
|
26971
27245
|
const handleSeeked = React23.useCallback((player) => {
|
|
26972
27246
|
console.log("[CroppedHlsVideoPlayer] Video seeked");
|
|
26973
|
-
|
|
27247
|
+
hiddenVideoRef.current?.play()?.catch(() => {
|
|
27248
|
+
});
|
|
27249
|
+
userSeekingRef.current = false;
|
|
27250
|
+
if (crop) {
|
|
26974
27251
|
renderFrameToCanvas();
|
|
26975
27252
|
}
|
|
26976
27253
|
onSeekedProp?.(player);
|
|
@@ -26978,8 +27255,29 @@ var CroppedHlsVideoPlayer = React23.forwardRef(({
|
|
|
26978
27255
|
const handleLoadedMetadata = React23.useCallback((player) => {
|
|
26979
27256
|
console.log("[CroppedHlsVideoPlayer] Video metadata loaded");
|
|
26980
27257
|
calculateCanvasDimensions();
|
|
27258
|
+
if (hiddenVideoRef.current?.video) {
|
|
27259
|
+
setDuration(hiddenVideoRef.current.video.duration || 0);
|
|
27260
|
+
}
|
|
27261
|
+
requestAnimationFrame(() => renderFrameToCanvas());
|
|
26981
27262
|
onLoadedMetadataProp?.(player);
|
|
26982
|
-
}, [calculateCanvasDimensions, onLoadedMetadataProp]);
|
|
27263
|
+
}, [calculateCanvasDimensions, onLoadedMetadataProp, renderFrameToCanvas]);
|
|
27264
|
+
const handleTimeUpdate = React23.useCallback((player, time2) => {
|
|
27265
|
+
setCurrentTime(time2);
|
|
27266
|
+
if (hiddenVideoRef.current?.video && hiddenVideoRef.current.video.buffered.length > 0) {
|
|
27267
|
+
const video = hiddenVideoRef.current.video;
|
|
27268
|
+
for (let i = 0; i < video.buffered.length; i++) {
|
|
27269
|
+
if (video.buffered.start(i) <= time2 && video.buffered.end(i) >= time2) {
|
|
27270
|
+
setBuffered(video.buffered.end(i));
|
|
27271
|
+
break;
|
|
27272
|
+
}
|
|
27273
|
+
}
|
|
27274
|
+
}
|
|
27275
|
+
videoProps.onTimeUpdate?.(player, time2);
|
|
27276
|
+
}, [videoProps.onTimeUpdate]);
|
|
27277
|
+
const handleDurationChange = React23.useCallback((player, dur) => {
|
|
27278
|
+
setDuration(dur);
|
|
27279
|
+
videoProps.onDurationChange?.(player, dur);
|
|
27280
|
+
}, [videoProps.onDurationChange]);
|
|
26983
27281
|
React23.useEffect(() => {
|
|
26984
27282
|
calculateCanvasDimensions();
|
|
26985
27283
|
const handleResize = () => {
|
|
@@ -27007,33 +27305,97 @@ var CroppedHlsVideoPlayer = React23.forwardRef(({
|
|
|
27007
27305
|
stopCanvasRendering();
|
|
27008
27306
|
};
|
|
27009
27307
|
}, [stopCanvasRendering]);
|
|
27308
|
+
const resetControlsTimeout = React23.useCallback(() => {
|
|
27309
|
+
if (controlsPinned) {
|
|
27310
|
+
setShowControls(true);
|
|
27311
|
+
return;
|
|
27312
|
+
}
|
|
27313
|
+
setShowControls(true);
|
|
27314
|
+
if (controlsTimeoutRef.current) {
|
|
27315
|
+
clearTimeout(controlsTimeoutRef.current);
|
|
27316
|
+
}
|
|
27317
|
+
if (isPlaying) {
|
|
27318
|
+
controlsTimeoutRef.current = setTimeout(() => {
|
|
27319
|
+
setShowControls(false);
|
|
27320
|
+
}, 3e3);
|
|
27321
|
+
}
|
|
27322
|
+
}, [isPlaying, controlsPinned]);
|
|
27323
|
+
const handleMouseMove = React23.useCallback(() => {
|
|
27324
|
+
resetControlsTimeout();
|
|
27325
|
+
}, [resetControlsTimeout]);
|
|
27326
|
+
React23.useEffect(() => {
|
|
27327
|
+
resetControlsTimeout();
|
|
27328
|
+
return () => {
|
|
27329
|
+
if (controlsTimeoutRef.current) {
|
|
27330
|
+
clearTimeout(controlsTimeoutRef.current);
|
|
27331
|
+
}
|
|
27332
|
+
};
|
|
27333
|
+
}, [isPlaying, resetControlsTimeout]);
|
|
27334
|
+
const handleTogglePlay = React23.useCallback(() => {
|
|
27335
|
+
if (hiddenVideoRef.current?.video) {
|
|
27336
|
+
if (hiddenVideoRef.current.video.paused) {
|
|
27337
|
+
hiddenVideoRef.current.play();
|
|
27338
|
+
} else {
|
|
27339
|
+
hiddenVideoRef.current.pause();
|
|
27340
|
+
}
|
|
27341
|
+
}
|
|
27342
|
+
}, []);
|
|
27343
|
+
const handleSeek = React23.useCallback((time2) => {
|
|
27344
|
+
if (hiddenVideoRef.current) {
|
|
27345
|
+
hiddenVideoRef.current.currentTime(time2);
|
|
27346
|
+
hiddenVideoRef.current.play()?.catch(() => {
|
|
27347
|
+
});
|
|
27348
|
+
setTimeout(() => renderFrameToCanvas(), 50);
|
|
27349
|
+
}
|
|
27350
|
+
}, [renderFrameToCanvas]);
|
|
27351
|
+
const handleSeekStart = React23.useCallback(() => {
|
|
27352
|
+
userSeekingRef.current = true;
|
|
27353
|
+
}, []);
|
|
27354
|
+
const handleSeekEnd = React23.useCallback(() => {
|
|
27355
|
+
if (hiddenVideoRef.current) {
|
|
27356
|
+
hiddenVideoRef.current.play()?.catch(() => {
|
|
27357
|
+
});
|
|
27358
|
+
}
|
|
27359
|
+
}, []);
|
|
27360
|
+
const handlePlaybackRateChange = React23.useCallback((rate) => {
|
|
27361
|
+
if (hiddenVideoRef.current) {
|
|
27362
|
+
hiddenVideoRef.current.playbackRate(rate);
|
|
27363
|
+
setPlaybackRate(rate);
|
|
27364
|
+
}
|
|
27365
|
+
}, []);
|
|
27366
|
+
const handleToggleFullscreen = React23.useCallback(() => {
|
|
27367
|
+
if (videoContainerRef.current) {
|
|
27368
|
+
if (!document.fullscreenElement) {
|
|
27369
|
+
videoContainerRef.current.requestFullscreen();
|
|
27370
|
+
} else {
|
|
27371
|
+
document.exitFullscreen();
|
|
27372
|
+
}
|
|
27373
|
+
}
|
|
27374
|
+
}, []);
|
|
27010
27375
|
if (!crop) {
|
|
27011
|
-
return /* @__PURE__ */ jsxRuntime.jsx(HlsVideoPlayer, { ref, ...videoProps, onClick });
|
|
27012
|
-
}
|
|
27013
|
-
const
|
|
27014
|
-
if (!onClick
|
|
27015
|
-
|
|
27016
|
-
|
|
27017
|
-
|
|
27018
|
-
setShowIndicator(false);
|
|
27019
|
-
setTimeout(() => {
|
|
27020
|
-
indicatorKeyRef.current += 1;
|
|
27021
|
-
setShowIndicator(true);
|
|
27022
|
-
}, 0);
|
|
27023
|
-
onClick();
|
|
27376
|
+
return /* @__PURE__ */ jsxRuntime.jsx(HlsVideoPlayer, { ref, ...videoProps, onClick, controls });
|
|
27377
|
+
}
|
|
27378
|
+
const handleClick = () => {
|
|
27379
|
+
if (!onClick && !controls) {
|
|
27380
|
+
handleTogglePlay();
|
|
27381
|
+
}
|
|
27382
|
+
if (onClick) onClick();
|
|
27024
27383
|
};
|
|
27025
27384
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
27026
27385
|
"div",
|
|
27027
27386
|
{
|
|
27028
27387
|
ref: videoContainerRef,
|
|
27029
|
-
className: `relative w-full h-full flex items-center justify-center bg-black ${onClick ? "cursor-pointer" : ""}
|
|
27030
|
-
onClick:
|
|
27388
|
+
className: `relative w-full h-full flex items-center justify-center bg-black group ${inheritedClassName} ${onClick || controls ? "cursor-pointer" : ""}`,
|
|
27389
|
+
onClick: handleClick,
|
|
27390
|
+
onMouseMove: handleMouseMove,
|
|
27391
|
+
onMouseLeave: () => isPlaying && !controlsPinned && setShowControls(false),
|
|
27031
27392
|
children: [
|
|
27032
27393
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
27033
27394
|
HlsVideoPlayer,
|
|
27034
27395
|
{
|
|
27035
27396
|
ref: hiddenVideoRef,
|
|
27036
27397
|
...videoProps,
|
|
27398
|
+
controls: false,
|
|
27037
27399
|
onReady: handleVideoReady,
|
|
27038
27400
|
onPlay: handleVideoPlay,
|
|
27039
27401
|
onPause: handleVideoPause,
|
|
@@ -27043,7 +27405,9 @@ var CroppedHlsVideoPlayer = React23.forwardRef(({
|
|
|
27043
27405
|
onLoadedMetadata: handleLoadedMetadata,
|
|
27044
27406
|
onLoadedData: videoProps.onLoadedData,
|
|
27045
27407
|
onPlaying: videoProps.onPlaying,
|
|
27046
|
-
onLoadingChange: videoProps.onLoadingChange
|
|
27408
|
+
onLoadingChange: videoProps.onLoadingChange,
|
|
27409
|
+
onTimeUpdate: handleTimeUpdate,
|
|
27410
|
+
onDurationChange: handleDurationChange
|
|
27047
27411
|
}
|
|
27048
27412
|
) }),
|
|
27049
27413
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -27060,8 +27424,8 @@ var CroppedHlsVideoPlayer = React23.forwardRef(({
|
|
|
27060
27424
|
}
|
|
27061
27425
|
}
|
|
27062
27426
|
),
|
|
27063
|
-
!isVideoReady && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
|
|
27064
|
-
debug && isVideoReady && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-2 left-2 bg-black/80 text-white text-xs p-2 rounded font-mono", children: [
|
|
27427
|
+
!isVideoReady && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
|
|
27428
|
+
debug && isVideoReady && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-2 left-2 bg-black/80 text-white text-xs p-2 rounded font-mono pointer-events-none z-20", children: [
|
|
27065
27429
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
27066
27430
|
"Crop: ",
|
|
27067
27431
|
crop.x,
|
|
@@ -27085,13 +27449,32 @@ var CroppedHlsVideoPlayer = React23.forwardRef(({
|
|
|
27085
27449
|
isProcessing ? "Yes" : "No"
|
|
27086
27450
|
] })
|
|
27087
27451
|
] }),
|
|
27088
|
-
|
|
27089
|
-
|
|
27452
|
+
controls && isVideoReady && /* @__PURE__ */ jsxRuntime.jsx(
|
|
27453
|
+
VideoControls,
|
|
27090
27454
|
{
|
|
27091
|
-
|
|
27092
|
-
|
|
27093
|
-
|
|
27094
|
-
|
|
27455
|
+
isPlaying,
|
|
27456
|
+
currentTime,
|
|
27457
|
+
duration,
|
|
27458
|
+
buffered,
|
|
27459
|
+
showControls: controlsPinned || showControls || !isPlaying,
|
|
27460
|
+
controlsPinned,
|
|
27461
|
+
playbackRate,
|
|
27462
|
+
onPlayPause: handleTogglePlay,
|
|
27463
|
+
onSeek: handleSeek,
|
|
27464
|
+
onSeekStart: handleSeekStart,
|
|
27465
|
+
onSeekEnd: handleSeekEnd,
|
|
27466
|
+
onPlaybackRateChange: handlePlaybackRateChange,
|
|
27467
|
+
onTogglePinControls: () => setControlsPinned((prev) => {
|
|
27468
|
+
const next = !prev;
|
|
27469
|
+
if (next) {
|
|
27470
|
+
setShowControls(true);
|
|
27471
|
+
} else {
|
|
27472
|
+
resetControlsTimeout();
|
|
27473
|
+
}
|
|
27474
|
+
return next;
|
|
27475
|
+
}),
|
|
27476
|
+
onToggleFullscreen: handleToggleFullscreen
|
|
27477
|
+
}
|
|
27095
27478
|
)
|
|
27096
27479
|
]
|
|
27097
27480
|
}
|
|
@@ -27630,6 +28013,67 @@ var SilentErrorBoundary = class extends React23__namespace.default.Component {
|
|
|
27630
28013
|
] }) });
|
|
27631
28014
|
}
|
|
27632
28015
|
};
|
|
28016
|
+
var PlayPauseIndicator = ({
|
|
28017
|
+
show,
|
|
28018
|
+
isPlaying,
|
|
28019
|
+
duration = 600
|
|
28020
|
+
}) => {
|
|
28021
|
+
const [isVisible, setIsVisible] = React23.useState(false);
|
|
28022
|
+
const [isFading, setIsFading] = React23.useState(false);
|
|
28023
|
+
React23.useEffect(() => {
|
|
28024
|
+
if (show) {
|
|
28025
|
+
setIsVisible(true);
|
|
28026
|
+
setIsFading(false);
|
|
28027
|
+
const fadeTimer = setTimeout(() => {
|
|
28028
|
+
setIsFading(true);
|
|
28029
|
+
}, 100);
|
|
28030
|
+
const hideTimer = setTimeout(() => {
|
|
28031
|
+
setIsVisible(false);
|
|
28032
|
+
setIsFading(false);
|
|
28033
|
+
}, duration);
|
|
28034
|
+
return () => {
|
|
28035
|
+
clearTimeout(fadeTimer);
|
|
28036
|
+
clearTimeout(hideTimer);
|
|
28037
|
+
};
|
|
28038
|
+
}
|
|
28039
|
+
}, [show, duration]);
|
|
28040
|
+
if (!isVisible) return null;
|
|
28041
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
28042
|
+
"div",
|
|
28043
|
+
{
|
|
28044
|
+
className: "absolute inset-0 flex items-center justify-center pointer-events-none z-10",
|
|
28045
|
+
style: {
|
|
28046
|
+
opacity: isFading ? 0 : 1,
|
|
28047
|
+
transition: `opacity ${duration - 100}ms ease-out`
|
|
28048
|
+
},
|
|
28049
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-black/70 rounded-full p-6", children: isPlaying ? (
|
|
28050
|
+
// Play icon (triangle)
|
|
28051
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
28052
|
+
"svg",
|
|
28053
|
+
{
|
|
28054
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
28055
|
+
viewBox: "0 0 24 24",
|
|
28056
|
+
fill: "white",
|
|
28057
|
+
className: "w-16 h-16",
|
|
28058
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 5v14l11-7z" })
|
|
28059
|
+
}
|
|
28060
|
+
)
|
|
28061
|
+
) : (
|
|
28062
|
+
// Pause icon (two bars)
|
|
28063
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
28064
|
+
"svg",
|
|
28065
|
+
{
|
|
28066
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
28067
|
+
viewBox: "0 0 24 24",
|
|
28068
|
+
fill: "white",
|
|
28069
|
+
className: "w-16 h-16",
|
|
28070
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 4h4v16H6V4zm8 0h4v16h-4V4z" })
|
|
28071
|
+
}
|
|
28072
|
+
)
|
|
28073
|
+
) })
|
|
28074
|
+
}
|
|
28075
|
+
);
|
|
28076
|
+
};
|
|
27633
28077
|
var BackButton = ({
|
|
27634
28078
|
onClick,
|
|
27635
28079
|
text = "Back",
|
|
@@ -31049,7 +31493,7 @@ function DiagnosisVideoModal({
|
|
|
31049
31493
|
}
|
|
31050
31494
|
loadClip();
|
|
31051
31495
|
}, [clipId, supabase, transformPlaylistUrls]);
|
|
31052
|
-
const
|
|
31496
|
+
const formatTime4 = (seconds) => {
|
|
31053
31497
|
const mins = Math.floor(seconds / 60);
|
|
31054
31498
|
const secs = Math.floor(seconds % 60);
|
|
31055
31499
|
return `${mins}:${secs.toString().padStart(2, "0")}`;
|
|
@@ -31241,9 +31685,9 @@ function DiagnosisVideoModal({
|
|
|
31241
31685
|
}
|
|
31242
31686
|
),
|
|
31243
31687
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-medium", children: [
|
|
31244
|
-
|
|
31688
|
+
formatTime4(currentTime),
|
|
31245
31689
|
" / ",
|
|
31246
|
-
|
|
31690
|
+
formatTime4(duration)
|
|
31247
31691
|
] }),
|
|
31248
31692
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
31249
31693
|
"input",
|
|
@@ -33214,7 +33658,7 @@ var LinePdfGenerator = ({
|
|
|
33214
33658
|
}
|
|
33215
33659
|
hourEndTime.setSeconds(0);
|
|
33216
33660
|
hourEndTime.setMilliseconds(0);
|
|
33217
|
-
const
|
|
33661
|
+
const formatTime4 = (date2) => {
|
|
33218
33662
|
return date2.toLocaleTimeString("en-IN", {
|
|
33219
33663
|
hour: "2-digit",
|
|
33220
33664
|
minute: "2-digit",
|
|
@@ -33222,7 +33666,7 @@ var LinePdfGenerator = ({
|
|
|
33222
33666
|
timeZone: "Asia/Kolkata"
|
|
33223
33667
|
});
|
|
33224
33668
|
};
|
|
33225
|
-
return `${
|
|
33669
|
+
return `${formatTime4(hourStartTime)} - ${formatTime4(hourEndTime)}`;
|
|
33226
33670
|
});
|
|
33227
33671
|
};
|
|
33228
33672
|
const hourlyTimeRanges = lineInfo.metrics.shift_start ? getHourlyTimeRanges(lineInfo.metrics.shift_start, lineInfo.metrics.shift_end) : [];
|
|
@@ -39808,7 +40252,7 @@ var AIAgentView = () => {
|
|
|
39808
40252
|
}
|
|
39809
40253
|
return formattedLines.join("");
|
|
39810
40254
|
};
|
|
39811
|
-
const
|
|
40255
|
+
const formatTime4 = (timestamp) => {
|
|
39812
40256
|
const date = new Date(timestamp);
|
|
39813
40257
|
return date.toLocaleTimeString([], {
|
|
39814
40258
|
hour: "2-digit",
|
|
@@ -41072,7 +41516,7 @@ var AIAgentView = () => {
|
|
|
41072
41516
|
}
|
|
41073
41517
|
),
|
|
41074
41518
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `mt-1.5 sm:mt-2 flex items-center gap-2 text-xs text-gray-400 ${message.role === "user" ? "justify-end" : "justify-start"}`, children: [
|
|
41075
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children:
|
|
41519
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatTime4(message.created_at) }),
|
|
41076
41520
|
message.role === "assistant" && message.id !== -1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
41077
41521
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-1 h-1 bg-gray-300 rounded-full" }),
|
|
41078
41522
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Axel" })
|