analytica-frontend-lib 1.1.12 → 1.1.14

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.js CHANGED
@@ -4725,6 +4725,8 @@ var CardAudio = (0, import_react14.forwardRef)(
4725
4725
  const [duration, setDuration] = (0, import_react14.useState)(0);
4726
4726
  const [volume, setVolume] = (0, import_react14.useState)(1);
4727
4727
  const [showVolumeControl, setShowVolumeControl] = (0, import_react14.useState)(false);
4728
+ const [showSpeedMenu, setShowSpeedMenu] = (0, import_react14.useState)(false);
4729
+ const [playbackRate, setPlaybackRate] = (0, import_react14.useState)(1);
4728
4730
  const audioRef = (0, import_react14.useRef)(null);
4729
4731
  const formatTime2 = (time) => {
4730
4732
  const minutes = Math.floor(time / 60);
@@ -4778,6 +4780,16 @@ var CardAudio = (0, import_react14.forwardRef)(
4778
4780
  const toggleVolumeControl = () => {
4779
4781
  setShowVolumeControl(!showVolumeControl);
4780
4782
  };
4783
+ const toggleSpeedMenu = () => {
4784
+ setShowSpeedMenu(!showSpeedMenu);
4785
+ };
4786
+ const handleSpeedChange = (speed) => {
4787
+ setPlaybackRate(speed);
4788
+ if (audioRef.current) {
4789
+ audioRef.current.playbackRate = speed;
4790
+ }
4791
+ setShowSpeedMenu(false);
4792
+ };
4781
4793
  const getVolumeIcon = () => {
4782
4794
  if (volume === 0) {
4783
4795
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_phosphor_react12.SpeakerSimpleX, {});
@@ -4934,13 +4946,35 @@ var CardAudio = (0, import_react14.forwardRef)(
4934
4946
  }
4935
4947
  )
4936
4948
  ] }),
4937
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4938
- import_phosphor_react12.DotsThreeVertical,
4939
- {
4940
- size: 24,
4941
- className: "text-text-950 cursor-pointer hover:text-primary-600"
4942
- }
4943
- )
4949
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "relative", children: [
4950
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4951
+ "button",
4952
+ {
4953
+ type: "button",
4954
+ onClick: toggleSpeedMenu,
4955
+ className: "cursor-pointer text-text-950 hover:text-primary-600",
4956
+ "aria-label": "Op\xE7\xF5es de velocidade",
4957
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_phosphor_react12.DotsThreeVertical, { size: 24 })
4958
+ }
4959
+ ),
4960
+ showSpeedMenu && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "absolute bottom-full right-0 mb-2 p-2 bg-background border border-border-100 rounded-lg shadow-lg min-w-24 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex flex-col gap-1", children: [
4961
+ { speed: 1, label: "1x" },
4962
+ { speed: 1.5, label: "1.5x" },
4963
+ { speed: 2, label: "2x" }
4964
+ ].map(({ speed, label }) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4965
+ "button",
4966
+ {
4967
+ type: "button",
4968
+ onClick: () => handleSpeedChange(speed),
4969
+ className: cn(
4970
+ "px-3 py-1 text-sm text-left rounded hover:bg-border-50 transition-colors",
4971
+ playbackRate === speed ? "bg-primary-950 text-secondary-100 font-medium" : "text-text-950"
4972
+ ),
4973
+ children: label
4974
+ },
4975
+ speed
4976
+ )) }) })
4977
+ ] })
4944
4978
  ]
4945
4979
  }
4946
4980
  );
@@ -6828,6 +6862,7 @@ var import_phosphor_react18 = require("phosphor-react");
6828
6862
  var import_jsx_runtime36 = require("react/jsx-runtime");
6829
6863
  var CONTROLS_HIDE_TIMEOUT = 3e3;
6830
6864
  var LEAVE_HIDE_TIMEOUT = 1e3;
6865
+ var INIT_DELAY = 100;
6831
6866
  var formatTime = (seconds) => {
6832
6867
  if (!seconds || isNaN(seconds)) return "0:00";
6833
6868
  const mins = Math.floor(seconds / 60);
@@ -6946,14 +6981,20 @@ var VideoPlayer = ({
6946
6981
  const trackRef = (0, import_react22.useRef)(null);
6947
6982
  const controlsTimeoutRef = (0, import_react22.useRef)(null);
6948
6983
  const lastMousePositionRef = (0, import_react22.useRef)({ x: 0, y: 0 });
6949
- const mouseMoveTimeoutRef = (0, import_react22.useRef)(null);
6950
6984
  const isUserInteracting = (0, import_react22.useCallback)(() => {
6951
- if (showSpeedMenu) return true;
6985
+ if (showSpeedMenu) {
6986
+ return true;
6987
+ }
6952
6988
  const activeElement = document.activeElement;
6953
6989
  const videoContainer = videoRef.current?.parentElement;
6954
6990
  if (activeElement && videoContainer?.contains(activeElement)) {
6991
+ if (activeElement === videoRef.current) {
6992
+ return false;
6993
+ }
6955
6994
  const isControl = activeElement.matches("button, input, [tabindex]");
6956
- if (isControl) return true;
6995
+ if (isControl) {
6996
+ return true;
6997
+ }
6957
6998
  }
6958
6999
  return false;
6959
7000
  }, [showSpeedMenu]);
@@ -6963,21 +7004,21 @@ var VideoPlayer = ({
6963
7004
  controlsTimeoutRef.current = null;
6964
7005
  }
6965
7006
  }, []);
6966
- const clearMouseMoveTimeout = (0, import_react22.useCallback)(() => {
6967
- if (mouseMoveTimeoutRef.current) {
6968
- clearTimeout(mouseMoveTimeoutRef.current);
6969
- mouseMoveTimeoutRef.current = null;
6970
- }
6971
- }, []);
6972
7007
  const showControlsWithTimer = (0, import_react22.useCallback)(() => {
6973
7008
  setShowControls(true);
6974
7009
  clearControlsTimeout();
6975
- if (isPlaying) {
7010
+ if (isFullscreen) {
7011
+ if (isPlaying) {
7012
+ controlsTimeoutRef.current = window.setTimeout(() => {
7013
+ setShowControls(false);
7014
+ }, CONTROLS_HIDE_TIMEOUT);
7015
+ }
7016
+ } else {
6976
7017
  controlsTimeoutRef.current = window.setTimeout(() => {
6977
7018
  setShowControls(false);
6978
7019
  }, CONTROLS_HIDE_TIMEOUT);
6979
7020
  }
6980
- }, [isPlaying, clearControlsTimeout]);
7021
+ }, [isFullscreen, isPlaying, clearControlsTimeout]);
6981
7022
  const handleMouseMove = (0, import_react22.useCallback)(
6982
7023
  (event) => {
6983
7024
  const currentX = event.clientX;
@@ -6991,14 +7032,18 @@ var VideoPlayer = ({
6991
7032
  },
6992
7033
  [showControlsWithTimer]
6993
7034
  );
7035
+ const handleMouseEnter = (0, import_react22.useCallback)(() => {
7036
+ showControlsWithTimer();
7037
+ }, [showControlsWithTimer]);
6994
7038
  const handleMouseLeave = (0, import_react22.useCallback)(() => {
7039
+ const userInteracting = isUserInteracting();
6995
7040
  clearControlsTimeout();
6996
- if (isPlaying && !isUserInteracting()) {
7041
+ if (!isFullscreen && !userInteracting) {
6997
7042
  controlsTimeoutRef.current = window.setTimeout(() => {
6998
7043
  setShowControls(false);
6999
7044
  }, LEAVE_HIDE_TIMEOUT);
7000
7045
  }
7001
- }, [isPlaying, clearControlsTimeout, isUserInteracting]);
7046
+ }, [isFullscreen, clearControlsTimeout, isUserInteracting]);
7002
7047
  (0, import_react22.useEffect)(() => {
7003
7048
  if (videoRef.current) {
7004
7049
  videoRef.current.volume = volume;
@@ -7025,9 +7070,13 @@ var VideoPlayer = ({
7025
7070
  showControlsWithTimer();
7026
7071
  } else {
7027
7072
  clearControlsTimeout();
7028
- setShowControls(true);
7073
+ if (isFullscreen) {
7074
+ setShowControls(true);
7075
+ } else {
7076
+ showControlsWithTimer();
7077
+ }
7029
7078
  }
7030
- }, [isPlaying, showControlsWithTimer, clearControlsTimeout]);
7079
+ }, [isPlaying, isFullscreen, showControlsWithTimer, clearControlsTimeout]);
7031
7080
  (0, import_react22.useEffect)(() => {
7032
7081
  const handleFullscreenChange = () => {
7033
7082
  const isCurrentlyFullscreen = !!document.fullscreenElement;
@@ -7041,6 +7090,28 @@ var VideoPlayer = ({
7041
7090
  document.removeEventListener("fullscreenchange", handleFullscreenChange);
7042
7091
  };
7043
7092
  }, [showControlsWithTimer]);
7093
+ (0, import_react22.useEffect)(() => {
7094
+ const init = () => {
7095
+ if (!isFullscreen) {
7096
+ showControlsWithTimer();
7097
+ }
7098
+ };
7099
+ let raf1 = 0, raf2 = 0, tid;
7100
+ if (typeof window.requestAnimationFrame === "function") {
7101
+ raf1 = requestAnimationFrame(() => {
7102
+ raf2 = requestAnimationFrame(init);
7103
+ });
7104
+ return () => {
7105
+ cancelAnimationFrame(raf1);
7106
+ cancelAnimationFrame(raf2);
7107
+ };
7108
+ } else {
7109
+ tid = window.setTimeout(init, INIT_DELAY);
7110
+ return () => {
7111
+ if (tid) clearTimeout(tid);
7112
+ };
7113
+ }
7114
+ }, []);
7044
7115
  const getInitialTime = (0, import_react22.useCallback)(() => {
7045
7116
  if (!autoSave || !storageKey) {
7046
7117
  return Number.isFinite(initialTime) && initialTime >= 0 ? initialTime : void 0;
@@ -7197,22 +7268,15 @@ var VideoPlayer = ({
7197
7268
  document.removeEventListener("visibilitychange", handleVisibilityChange);
7198
7269
  window.removeEventListener("blur", handleBlur);
7199
7270
  clearControlsTimeout();
7200
- clearMouseMoveTimeout();
7201
7271
  };
7202
- }, [isPlaying, clearControlsTimeout, clearMouseMoveTimeout]);
7272
+ }, [isPlaying, clearControlsTimeout]);
7203
7273
  const progressPercentage = duration > 0 ? currentTime / duration * 100 : 0;
7204
7274
  const getTopControlsOpacity = (0, import_react22.useCallback)(() => {
7205
- if (isFullscreen) {
7206
- return showControls ? "opacity-100" : "opacity-0";
7207
- }
7208
- return !isPlaying || showControls ? "opacity-100" : "opacity-0 group-hover:opacity-100";
7209
- }, [isFullscreen, showControls, isPlaying]);
7275
+ return showControls ? "opacity-100" : "opacity-0";
7276
+ }, [showControls]);
7210
7277
  const getBottomControlsOpacity = (0, import_react22.useCallback)(() => {
7211
- if (isFullscreen) {
7212
- return showControls ? "opacity-100" : "opacity-0";
7213
- }
7214
- return !isPlaying || showControls ? "opacity-100" : "opacity-0 group-hover:opacity-100";
7215
- }, [isFullscreen, showControls, isPlaying]);
7278
+ return showControls ? "opacity-100" : "opacity-0";
7279
+ }, [showControls]);
7216
7280
  const handleVideoKeyDown = (0, import_react22.useCallback)(
7217
7281
  (e) => {
7218
7282
  if (e.key) {
@@ -7269,7 +7333,7 @@ var VideoPlayer = ({
7269
7333
  ]
7270
7334
  );
7271
7335
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: cn("flex flex-col", className), children: [
7272
- (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: [
7336
+ (title || subtitleText) && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "bg-subject-1 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: [
7273
7337
  title && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7274
7338
  Text_default,
7275
7339
  {
@@ -7298,13 +7362,14 @@ var VideoPlayer = ({
7298
7362
  {
7299
7363
  className: cn(
7300
7364
  "relative w-full bg-background overflow-hidden group",
7301
- title || subtitleText ? "rounded-b-xl" : "rounded-xl",
7365
+ "rounded-b-xl",
7302
7366
  // Hide cursor when controls are hidden and video is playing
7303
7367
  isPlaying && !showControls ? "cursor-none group-hover:cursor-default" : "cursor-default"
7304
7368
  ),
7305
7369
  "aria-label": title ? `Video player: ${title}` : "Video player",
7306
7370
  onMouseMove: handleMouseMove,
7307
- onMouseEnter: showControlsWithTimer,
7371
+ onMouseEnter: handleMouseEnter,
7372
+ onTouchStart: handleMouseEnter,
7308
7373
  onMouseLeave: handleMouseLeave,
7309
7374
  children: [
7310
7375
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(