@acoustte-digital-services/digitalstore-controls-dev 0.8.1-dev.20260422124624 → 0.8.1-dev.20260423051720

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.
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  HlsPlayer_default
4
- } from "./chunk-NTZ3IUOL.mjs";
4
+ } from "./chunk-VNSFFK3H.mjs";
5
5
  export {
6
6
  HlsPlayer_default as default
7
7
  };
@@ -19,7 +19,10 @@ var HlsPlayer = React.memo(
19
19
  const [isPlaying, setIsPlaying] = useState(playOptions === "autoplay");
20
20
  const [isHovered, setIsHovered] = useState(false);
21
21
  const [isMobile, setIsMobile] = useState(false);
22
+ const [isControlsVisible, setIsControlsVisible] = useState(true);
22
23
  const wasManuallyPausedRef = useRef(false);
24
+ const inactivityTimerRef = useRef(null);
25
+ const INACTIVITY_DELAY = 2500;
23
26
  const resolvedSources = sources && sources.length > 0 ? sources : assetUrl ? [{ src: assetUrl, posterUrl }] : [];
24
27
  useEffect(() => {
25
28
  const checkMobile = () => {
@@ -34,6 +37,27 @@ var HlsPlayer = React.memo(
34
37
  window.addEventListener("resize", checkMobile);
35
38
  return () => window.removeEventListener("resize", checkMobile);
36
39
  }, []);
40
+ const resetInactivityTimer = useCallback(() => {
41
+ setIsControlsVisible(true);
42
+ if (inactivityTimerRef.current) clearTimeout(inactivityTimerRef.current);
43
+ if (isPlaying) {
44
+ inactivityTimerRef.current = setTimeout(
45
+ () => setIsControlsVisible(false),
46
+ INACTIVITY_DELAY
47
+ );
48
+ }
49
+ }, [isPlaying]);
50
+ useEffect(() => {
51
+ if (!isPlaying) {
52
+ if (inactivityTimerRef.current) clearTimeout(inactivityTimerRef.current);
53
+ setIsControlsVisible(true);
54
+ }
55
+ }, [isPlaying]);
56
+ useEffect(() => {
57
+ return () => {
58
+ if (inactivityTimerRef.current) clearTimeout(inactivityTimerRef.current);
59
+ };
60
+ }, []);
37
61
  useEffect(() => {
38
62
  const v = videoRef.current;
39
63
  if (!v || resolvedSources.length === 0) return;
@@ -81,19 +105,26 @@ var HlsPlayer = React.memo(
81
105
  const handleMouseEnter = useCallback(() => {
82
106
  if (isMobile) return;
83
107
  setIsHovered(true);
108
+ resetInactivityTimer();
84
109
  if (playOptions === "playOnHover" && videoRef.current && !wasManuallyPausedRef.current) {
85
110
  videoRef.current.play().then(() => setIsPlaying(true));
86
111
  }
87
- }, [playOptions, isMobile]);
112
+ }, [playOptions, isMobile, resetInactivityTimer]);
88
113
  const handleMouseLeave = useCallback(() => {
89
114
  if (isMobile) return;
90
115
  setIsHovered(false);
116
+ if (inactivityTimerRef.current) clearTimeout(inactivityTimerRef.current);
117
+ if (isPlaying) setIsControlsVisible(false);
91
118
  if (playOptions === "playOnHover" && videoRef.current) {
92
119
  videoRef.current.pause();
93
120
  videoRef.current.currentTime = 0;
94
121
  setIsPlaying(false);
95
122
  }
96
- }, [playOptions, isMobile]);
123
+ }, [playOptions, isMobile, isPlaying]);
124
+ const handleMouseMove = useCallback(() => {
125
+ if (isMobile) return;
126
+ resetInactivityTimer();
127
+ }, [isMobile, resetInactivityTimer]);
97
128
  const posterSources = resolvedSources.filter((s) => s.media && s.posterUrl);
98
129
  const fallbackPoster = posterUrl ?? resolvedSources.find((s) => !s.media)?.posterUrl ?? resolvedSources[0]?.posterUrl;
99
130
  if (resolvedSources.length === 0) return null;
@@ -103,6 +134,7 @@ var HlsPlayer = React.memo(
103
134
  className: "relative w-full aspect-video bg-black",
104
135
  onMouseEnter: handleMouseEnter,
105
136
  onMouseLeave: handleMouseLeave,
137
+ onMouseMove: handleMouseMove,
106
138
  children: [
107
139
  /* @__PURE__ */ jsx(
108
140
  "video",
@@ -115,7 +147,7 @@ var HlsPlayer = React.memo(
115
147
  autoPlay: playOptions === "autoplay",
116
148
  loop,
117
149
  playsInline: true,
118
- onClick: !isMobile && !isPlaying ? handlePlayPause : void 0,
150
+ onClick: !isMobile ? handlePlayPause : void 0,
119
151
  children: resolvedSources.map(({ src, media }, i) => /* @__PURE__ */ jsx(
120
152
  "source",
121
153
  {
@@ -146,12 +178,63 @@ var HlsPlayer = React.memo(
146
178
  ]
147
179
  }
148
180
  ),
149
- !isMobile && !isPlaying && /* @__PURE__ */ jsx(
181
+ !isMobile && /* @__PURE__ */ jsx(
150
182
  "div",
151
183
  {
152
- className: "absolute inset-0 flex items-center justify-center cursor-pointer",
153
- onClick: handlePlayPause,
154
- children: "\u25B6"
184
+ className: "absolute inset-0 flex items-center justify-center pointer-events-none",
185
+ style: {
186
+ opacity: isControlsVisible ? 1 : 0,
187
+ transition: "opacity 0.3s ease"
188
+ },
189
+ children: /* @__PURE__ */ jsx(
190
+ "button",
191
+ {
192
+ type: "button",
193
+ "aria-label": isPlaying ? "Pause" : "Play",
194
+ onClick: (e) => {
195
+ e.stopPropagation();
196
+ handlePlayPause();
197
+ },
198
+ style: {
199
+ pointerEvents: isControlsVisible ? "auto" : "none",
200
+ width: 64,
201
+ height: 64,
202
+ borderRadius: "50%",
203
+ border: "1.5px solid rgba(255,255,255,0.18)",
204
+ cursor: "pointer",
205
+ display: "flex",
206
+ alignItems: "center",
207
+ justifyContent: "center",
208
+ background: "rgba(0, 0, 0, 0.45)",
209
+ backdropFilter: "blur(10px)",
210
+ WebkitBackdropFilter: "blur(10px)",
211
+ boxShadow: "0 4px 32px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.1)",
212
+ transition: "transform 0.18s ease, background 0.18s ease, border-color 0.18s ease"
213
+ },
214
+ onMouseEnter: (e) => {
215
+ const btn = e.currentTarget;
216
+ btn.style.transform = "scale(1.1)";
217
+ btn.style.background = "rgba(0,0,0,0.65)";
218
+ btn.style.borderColor = "rgba(255,255,255,0.32)";
219
+ },
220
+ onMouseLeave: (e) => {
221
+ const btn = e.currentTarget;
222
+ btn.style.transform = "scale(1)";
223
+ btn.style.background = "rgba(0,0,0,0.45)";
224
+ btn.style.borderColor = "rgba(255,255,255,0.18)";
225
+ },
226
+ children: isPlaying ? (
227
+ /* Pause — two rounded bars */
228
+ /* @__PURE__ */ jsxs("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
229
+ /* @__PURE__ */ jsx("rect", { x: "3.5", y: "2.5", width: "4.5", height: "15", rx: "1.5", fill: "white" }),
230
+ /* @__PURE__ */ jsx("rect", { x: "12", y: "2.5", width: "4.5", height: "15", rx: "1.5", fill: "white" })
231
+ ] })
232
+ ) : (
233
+ /* Play — solid triangle, nudged right for optical balance */
234
+ /* @__PURE__ */ jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx("path", { d: "M5 3.5L17 10L5 16.5V3.5Z", fill: "white" }) })
235
+ )
236
+ }
237
+ )
155
238
  }
156
239
  )
157
240
  ]
package/dist/index.js CHANGED
@@ -296,7 +296,10 @@ var init_HlsPlayer = __esm({
296
296
  const [isPlaying, setIsPlaying] = (0, import_react33.useState)(playOptions === "autoplay");
297
297
  const [isHovered, setIsHovered] = (0, import_react33.useState)(false);
298
298
  const [isMobile, setIsMobile] = (0, import_react33.useState)(false);
299
+ const [isControlsVisible, setIsControlsVisible] = (0, import_react33.useState)(true);
299
300
  const wasManuallyPausedRef = (0, import_react33.useRef)(false);
301
+ const inactivityTimerRef = (0, import_react33.useRef)(null);
302
+ const INACTIVITY_DELAY = 2500;
300
303
  const resolvedSources = sources && sources.length > 0 ? sources : assetUrl ? [{ src: assetUrl, posterUrl }] : [];
301
304
  (0, import_react33.useEffect)(() => {
302
305
  const checkMobile = () => {
@@ -311,6 +314,27 @@ var init_HlsPlayer = __esm({
311
314
  window.addEventListener("resize", checkMobile);
312
315
  return () => window.removeEventListener("resize", checkMobile);
313
316
  }, []);
317
+ const resetInactivityTimer = (0, import_react33.useCallback)(() => {
318
+ setIsControlsVisible(true);
319
+ if (inactivityTimerRef.current) clearTimeout(inactivityTimerRef.current);
320
+ if (isPlaying) {
321
+ inactivityTimerRef.current = setTimeout(
322
+ () => setIsControlsVisible(false),
323
+ INACTIVITY_DELAY
324
+ );
325
+ }
326
+ }, [isPlaying]);
327
+ (0, import_react33.useEffect)(() => {
328
+ if (!isPlaying) {
329
+ if (inactivityTimerRef.current) clearTimeout(inactivityTimerRef.current);
330
+ setIsControlsVisible(true);
331
+ }
332
+ }, [isPlaying]);
333
+ (0, import_react33.useEffect)(() => {
334
+ return () => {
335
+ if (inactivityTimerRef.current) clearTimeout(inactivityTimerRef.current);
336
+ };
337
+ }, []);
314
338
  (0, import_react33.useEffect)(() => {
315
339
  const v = videoRef.current;
316
340
  if (!v || resolvedSources.length === 0) return;
@@ -358,19 +382,26 @@ var init_HlsPlayer = __esm({
358
382
  const handleMouseEnter = (0, import_react33.useCallback)(() => {
359
383
  if (isMobile) return;
360
384
  setIsHovered(true);
385
+ resetInactivityTimer();
361
386
  if (playOptions === "playOnHover" && videoRef.current && !wasManuallyPausedRef.current) {
362
387
  videoRef.current.play().then(() => setIsPlaying(true));
363
388
  }
364
- }, [playOptions, isMobile]);
389
+ }, [playOptions, isMobile, resetInactivityTimer]);
365
390
  const handleMouseLeave = (0, import_react33.useCallback)(() => {
366
391
  if (isMobile) return;
367
392
  setIsHovered(false);
393
+ if (inactivityTimerRef.current) clearTimeout(inactivityTimerRef.current);
394
+ if (isPlaying) setIsControlsVisible(false);
368
395
  if (playOptions === "playOnHover" && videoRef.current) {
369
396
  videoRef.current.pause();
370
397
  videoRef.current.currentTime = 0;
371
398
  setIsPlaying(false);
372
399
  }
373
- }, [playOptions, isMobile]);
400
+ }, [playOptions, isMobile, isPlaying]);
401
+ const handleMouseMove = (0, import_react33.useCallback)(() => {
402
+ if (isMobile) return;
403
+ resetInactivityTimer();
404
+ }, [isMobile, resetInactivityTimer]);
374
405
  const posterSources = resolvedSources.filter((s) => s.media && s.posterUrl);
375
406
  const fallbackPoster = posterUrl ?? resolvedSources.find((s) => !s.media)?.posterUrl ?? resolvedSources[0]?.posterUrl;
376
407
  if (resolvedSources.length === 0) return null;
@@ -380,6 +411,7 @@ var init_HlsPlayer = __esm({
380
411
  className: "relative w-full aspect-video bg-black",
381
412
  onMouseEnter: handleMouseEnter,
382
413
  onMouseLeave: handleMouseLeave,
414
+ onMouseMove: handleMouseMove,
383
415
  children: [
384
416
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
385
417
  "video",
@@ -392,7 +424,7 @@ var init_HlsPlayer = __esm({
392
424
  autoPlay: playOptions === "autoplay",
393
425
  loop,
394
426
  playsInline: true,
395
- onClick: !isMobile && !isPlaying ? handlePlayPause : void 0,
427
+ onClick: !isMobile ? handlePlayPause : void 0,
396
428
  children: resolvedSources.map(({ src, media }, i) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
397
429
  "source",
398
430
  {
@@ -423,12 +455,63 @@ var init_HlsPlayer = __esm({
423
455
  ]
424
456
  }
425
457
  ),
426
- !isMobile && !isPlaying && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
458
+ !isMobile && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
427
459
  "div",
428
460
  {
429
- className: "absolute inset-0 flex items-center justify-center cursor-pointer",
430
- onClick: handlePlayPause,
431
- children: "\u25B6"
461
+ className: "absolute inset-0 flex items-center justify-center pointer-events-none",
462
+ style: {
463
+ opacity: isControlsVisible ? 1 : 0,
464
+ transition: "opacity 0.3s ease"
465
+ },
466
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
467
+ "button",
468
+ {
469
+ type: "button",
470
+ "aria-label": isPlaying ? "Pause" : "Play",
471
+ onClick: (e) => {
472
+ e.stopPropagation();
473
+ handlePlayPause();
474
+ },
475
+ style: {
476
+ pointerEvents: isControlsVisible ? "auto" : "none",
477
+ width: 64,
478
+ height: 64,
479
+ borderRadius: "50%",
480
+ border: "1.5px solid rgba(255,255,255,0.18)",
481
+ cursor: "pointer",
482
+ display: "flex",
483
+ alignItems: "center",
484
+ justifyContent: "center",
485
+ background: "rgba(0, 0, 0, 0.45)",
486
+ backdropFilter: "blur(10px)",
487
+ WebkitBackdropFilter: "blur(10px)",
488
+ boxShadow: "0 4px 32px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.1)",
489
+ transition: "transform 0.18s ease, background 0.18s ease, border-color 0.18s ease"
490
+ },
491
+ onMouseEnter: (e) => {
492
+ const btn = e.currentTarget;
493
+ btn.style.transform = "scale(1.1)";
494
+ btn.style.background = "rgba(0,0,0,0.65)";
495
+ btn.style.borderColor = "rgba(255,255,255,0.32)";
496
+ },
497
+ onMouseLeave: (e) => {
498
+ const btn = e.currentTarget;
499
+ btn.style.transform = "scale(1)";
500
+ btn.style.background = "rgba(0,0,0,0.45)";
501
+ btn.style.borderColor = "rgba(255,255,255,0.18)";
502
+ },
503
+ children: isPlaying ? (
504
+ /* Pause — two rounded bars */
505
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
506
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("rect", { x: "3.5", y: "2.5", width: "4.5", height: "15", rx: "1.5", fill: "white" }),
507
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("rect", { x: "12", y: "2.5", width: "4.5", height: "15", rx: "1.5", fill: "white" })
508
+ ] })
509
+ ) : (
510
+ /* Play — solid triangle, nudged right for optical balance */
511
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("path", { d: "M5 3.5L17 10L5 16.5V3.5Z", fill: "white" }) })
512
+ )
513
+ }
514
+ )
432
515
  }
433
516
  )
434
517
  ]
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HlsPlayer_default
3
- } from "./chunk-NTZ3IUOL.mjs";
3
+ } from "./chunk-VNSFFK3H.mjs";
4
4
  import {
5
5
  Button_default,
6
6
  ServiceClient_default,
@@ -2628,7 +2628,7 @@ var DeviceAssetSelector_default = DeviceAssetSelector;
2628
2628
 
2629
2629
  // src/components/pageRenderingEngine/nodes/ImageNode.tsx
2630
2630
  import { Fragment as Fragment3, jsx as jsx39 } from "react/jsx-runtime";
2631
- var HlsPlayer = dynamic(() => import("./HlsPlayer-KOTCX7MY.mjs"), {
2631
+ var HlsPlayer = dynamic(() => import("./HlsPlayer-CTZICLSJ.mjs"), {
2632
2632
  ssr: false
2633
2633
  });
2634
2634
  var getNestedValue = (obj, path) => {
@@ -4097,7 +4097,7 @@ var Pagination_default = Pagination;
4097
4097
  // src/components/pageRenderingEngine/nodes/ImageGalleryNode.tsx
4098
4098
  import dynamic5 from "next/dynamic";
4099
4099
  import { Fragment as Fragment9, jsx as jsx58, jsxs as jsxs33 } from "react/jsx-runtime";
4100
- var HlsPlayer2 = dynamic5(() => import("./HlsPlayer-KOTCX7MY.mjs"), { ssr: false });
4100
+ var HlsPlayer2 = dynamic5(() => import("./HlsPlayer-CTZICLSJ.mjs"), { ssr: false });
4101
4101
  var deviceToMediaQuery = (device) => {
4102
4102
  switch (device) {
4103
4103
  case "sm":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acoustte-digital-services/digitalstore-controls-dev",
3
- "version": "0.8.1-dev.20260422124624",
3
+ "version": "0.8.1-dev.20260423051720",
4
4
  "description": "Reusable React components",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",