analytica-frontend-lib 1.1.90 → 1.1.92

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.
@@ -346,7 +346,6 @@ var DownloadButton = ({
346
346
  await new Promise((resolve) => setTimeout(resolve, 200));
347
347
  }
348
348
  } catch (error) {
349
- console.error(`Erro ao baixar ${item.label}:`, error);
350
349
  onDownloadError?.(
351
350
  item.type,
352
351
  error instanceof Error ? error : new Error(`Falha ao baixar ${item.label}`)
@@ -572,6 +571,7 @@ var VideoPlayer = ({
572
571
  const [showControls, setShowControls] = useState3(true);
573
572
  const [hasCompleted, setHasCompleted] = useState3(false);
574
573
  const [showCaptions, setShowCaptions] = useState3(false);
574
+ const [subtitlesValidation, setSubtitlesValidation] = useState3("idle");
575
575
  useEffect2(() => {
576
576
  setHasCompleted(false);
577
577
  }, [src]);
@@ -857,11 +857,12 @@ var VideoPlayer = ({
857
857
  setShowSpeedMenu(!showSpeedMenu);
858
858
  }, [showSpeedMenu]);
859
859
  const toggleCaptions = useCallback2(() => {
860
- if (!trackRef.current?.track || !subtitles) return;
860
+ if (!trackRef.current?.track || !subtitles || subtitlesValidation !== "valid")
861
+ return;
861
862
  const newShowCaptions = !showCaptions;
862
863
  setShowCaptions(newShowCaptions);
863
- trackRef.current.track.mode = newShowCaptions && subtitles ? "showing" : "hidden";
864
- }, [showCaptions, subtitles]);
864
+ trackRef.current.track.mode = newShowCaptions ? "showing" : "hidden";
865
+ }, [showCaptions, subtitles, subtitlesValidation]);
865
866
  const checkVideoCompletion = useCallback2(
866
867
  (progressPercent) => {
867
868
  if (progressPercent >= 95 && !hasCompleted) {
@@ -889,11 +890,58 @@ var VideoPlayer = ({
889
890
  setDuration(videoRef.current.duration);
890
891
  }
891
892
  }, []);
893
+ useEffect2(() => {
894
+ const controller = new AbortController();
895
+ const validateSubtitles = async () => {
896
+ if (!subtitles) {
897
+ setSubtitlesValidation("idle");
898
+ return;
899
+ }
900
+ setSubtitlesValidation("validating");
901
+ try {
902
+ if (subtitles.startsWith("data:")) {
903
+ setSubtitlesValidation("valid");
904
+ return;
905
+ }
906
+ const response = await fetch(subtitles, {
907
+ method: "HEAD",
908
+ signal: controller.signal
909
+ });
910
+ if (response.ok) {
911
+ const contentType = response.headers.get("content-type");
912
+ const isValidType = !contentType || contentType.includes("text/vtt") || contentType.includes("text/plain") || contentType.includes("application/octet-stream");
913
+ if (isValidType) {
914
+ setSubtitlesValidation("valid");
915
+ } else {
916
+ setSubtitlesValidation("invalid");
917
+ console.warn(
918
+ `Subtitles URL has invalid content type: ${contentType}`
919
+ );
920
+ }
921
+ } else {
922
+ setSubtitlesValidation("invalid");
923
+ console.warn(
924
+ `Subtitles URL returned status: ${response.status} ${response.statusText}`
925
+ );
926
+ }
927
+ } catch (error) {
928
+ if (error instanceof Error && error.name === "AbortError") {
929
+ return;
930
+ }
931
+ console.warn("Subtitles URL validation failed:", error);
932
+ setSubtitlesValidation("invalid");
933
+ }
934
+ };
935
+ validateSubtitles();
936
+ return () => {
937
+ controller.abort();
938
+ };
939
+ }, [subtitles]);
892
940
  useEffect2(() => {
893
941
  if (trackRef.current?.track) {
894
- trackRef.current.track.mode = showCaptions && subtitles ? "showing" : "hidden";
942
+ trackRef.current.track.mode = showCaptions && subtitles && subtitlesValidation === "valid" ? "showing" : "hidden";
895
943
  }
896
- }, [subtitles, showCaptions]);
944
+ }, [subtitles, showCaptions, subtitlesValidation]);
897
945
  useEffect2(() => {
898
946
  const handleVisibilityChange = () => {
899
947
  if (document.hidden && isPlaying && videoRef.current) {
@@ -947,61 +995,57 @@ var VideoPlayer = ({
947
995
  const getBottomControlsOpacity = useCallback2(() => {
948
996
  return showControls ? "opacity-100" : "opacity-0";
949
997
  }, [showControls]);
998
+ const seekBackward = useCallback2(() => {
999
+ if (videoRef.current) {
1000
+ videoRef.current.currentTime -= 10;
1001
+ }
1002
+ }, []);
1003
+ const seekForward = useCallback2(() => {
1004
+ if (videoRef.current) {
1005
+ videoRef.current.currentTime += 10;
1006
+ }
1007
+ }, []);
1008
+ const increaseVolume = useCallback2(() => {
1009
+ handleVolumeChange(Math.min(100, volume * 100 + 10));
1010
+ }, [handleVolumeChange, volume]);
1011
+ const decreaseVolume = useCallback2(() => {
1012
+ handleVolumeChange(Math.max(0, volume * 100 - 10));
1013
+ }, [handleVolumeChange, volume]);
950
1014
  const handleVideoKeyDown = useCallback2(
951
1015
  (e) => {
952
- if (e.key) {
953
- e.stopPropagation();
954
- showControlsWithTimer();
955
- }
956
- switch (e.key) {
957
- case " ":
958
- case "Enter":
959
- e.preventDefault();
960
- togglePlayPause();
961
- break;
962
- case "ArrowLeft":
963
- e.preventDefault();
964
- if (videoRef.current) {
965
- videoRef.current.currentTime -= 10;
966
- }
967
- break;
968
- case "ArrowRight":
969
- e.preventDefault();
970
- if (videoRef.current) {
971
- videoRef.current.currentTime += 10;
972
- }
973
- break;
974
- case "ArrowUp":
975
- e.preventDefault();
976
- handleVolumeChange(Math.min(100, volume * 100 + 10));
977
- break;
978
- case "ArrowDown":
979
- e.preventDefault();
980
- handleVolumeChange(Math.max(0, volume * 100 - 10));
981
- break;
982
- case "m":
983
- case "M":
984
- e.preventDefault();
985
- toggleMute();
986
- break;
987
- case "f":
988
- case "F":
989
- e.preventDefault();
990
- toggleFullscreen();
991
- break;
992
- default:
993
- break;
1016
+ if (!e.key) return;
1017
+ e.stopPropagation();
1018
+ showControlsWithTimer();
1019
+ const keyHandlers = {
1020
+ " ": togglePlayPause,
1021
+ Enter: togglePlayPause,
1022
+ ArrowLeft: seekBackward,
1023
+ ArrowRight: seekForward,
1024
+ ArrowUp: increaseVolume,
1025
+ ArrowDown: decreaseVolume,
1026
+ m: toggleMute,
1027
+ M: toggleMute,
1028
+ f: toggleFullscreen,
1029
+ F: toggleFullscreen
1030
+ };
1031
+ const handler = keyHandlers[e.key];
1032
+ if (handler) {
1033
+ e.preventDefault();
1034
+ handler();
994
1035
  }
995
1036
  },
996
1037
  [
997
1038
  showControlsWithTimer,
998
1039
  togglePlayPause,
999
- handleVolumeChange,
1000
- volume,
1040
+ seekBackward,
1041
+ seekForward,
1042
+ increaseVolume,
1043
+ decreaseVolume,
1001
1044
  toggleMute,
1002
1045
  toggleFullscreen
1003
1046
  ]
1004
1047
  );
1048
+ const groupedSubTitleValid = subtitles && subtitlesValidation === "valid";
1005
1049
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col", className), children: [
1006
1050
  (title || subtitleText) && /* @__PURE__ */ jsxs("div", { className: "bg-subject-1 px-8 py-4 flex items-end justify-between min-h-20", children: [
1007
1051
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
@@ -1075,9 +1119,9 @@ var VideoPlayer = ({
1075
1119
  {
1076
1120
  ref: trackRef,
1077
1121
  kind: "captions",
1078
- src: subtitles || "data:text/vtt;charset=utf-8,WEBVTT",
1122
+ src: groupedSubTitleValid ? subtitles : "data:text/vtt;charset=utf-8,WEBVTT",
1079
1123
  srcLang: "pt-br",
1080
- label: subtitles ? "Legendas em Portugu\xEAs" : "Sem legendas dispon\xEDveis",
1124
+ label: groupedSubTitleValid ? "Legendas em Portugu\xEAs" : "Sem legendas dispon\xEDveis",
1081
1125
  default: false
1082
1126
  }
1083
1127
  )
@@ -1166,7 +1210,7 @@ var VideoPlayer = ({
1166
1210
  showSlider: !isUltraSmallMobile
1167
1211
  }
1168
1212
  ),
1169
- subtitles && /* @__PURE__ */ jsx4(
1213
+ groupedSubTitleValid && /* @__PURE__ */ jsx4(
1170
1214
  IconButton_default,
1171
1215
  {
1172
1216
  icon: /* @__PURE__ */ jsx4(ClosedCaptioning, { size: getIconSize() }),