softbuilders-react-video-player 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +126 -0
  3. package/dist/components/BigPlayButton/index.d.ts +9 -0
  4. package/dist/components/BigPlayButton/index.js +15 -0
  5. package/dist/components/BigPlayButton/index.js.map +1 -0
  6. package/dist/components/BufferTracker/index.d.ts +3 -0
  7. package/dist/components/BufferTracker/index.js +16 -0
  8. package/dist/components/BufferTracker/index.js.map +1 -0
  9. package/dist/components/ChapterTooltip/index.d.ts +11 -0
  10. package/dist/components/ChapterTooltip/index.js +36 -0
  11. package/dist/components/ChapterTooltip/index.js.map +1 -0
  12. package/dist/components/ChaptersPanal/index.d.ts +7 -0
  13. package/dist/components/ChaptersPanal/index.js +19 -0
  14. package/dist/components/ChaptersPanal/index.js.map +1 -0
  15. package/dist/components/ControlBar/index.d.ts +15 -0
  16. package/dist/components/ControlBar/index.js +64 -0
  17. package/dist/components/ControlBar/index.js.map +1 -0
  18. package/dist/components/CreateNoteMenu/index.d.ts +6 -0
  19. package/dist/components/CreateNoteMenu/index.js +29 -0
  20. package/dist/components/CreateNoteMenu/index.js.map +1 -0
  21. package/dist/components/CurrentTimeLabel/index.d.ts +4 -0
  22. package/dist/components/CurrentTimeLabel/index.js +10 -0
  23. package/dist/components/CurrentTimeLabel/index.js.map +1 -0
  24. package/dist/components/CurrentTimeTracker/index.d.ts +3 -0
  25. package/dist/components/CurrentTimeTracker/index.js +15 -0
  26. package/dist/components/CurrentTimeTracker/index.js.map +1 -0
  27. package/dist/components/Menu/index.d.ts +6 -0
  28. package/dist/components/Menu/index.js +11 -0
  29. package/dist/components/Menu/index.js.map +1 -0
  30. package/dist/components/MenuButton/index.d.ts +8 -0
  31. package/dist/components/MenuButton/index.js +31 -0
  32. package/dist/components/MenuButton/index.js.map +1 -0
  33. package/dist/components/NoteTooltip/index.d.ts +10 -0
  34. package/dist/components/NoteTooltip/index.js +24 -0
  35. package/dist/components/NoteTooltip/index.js.map +1 -0
  36. package/dist/components/NotesPanal/index.d.ts +7 -0
  37. package/dist/components/NotesPanal/index.js +17 -0
  38. package/dist/components/NotesPanal/index.js.map +1 -0
  39. package/dist/components/QualityMenu/index.d.ts +4 -0
  40. package/dist/components/QualityMenu/index.js +53 -0
  41. package/dist/components/QualityMenu/index.js.map +1 -0
  42. package/dist/components/Slider/index.d.ts +10 -0
  43. package/dist/components/Slider/index.js +22 -0
  44. package/dist/components/Slider/index.js.map +1 -0
  45. package/dist/components/Slider/style.css +15 -0
  46. package/dist/components/SoftBuildersVideoPlayer/index.d.ts +13 -0
  47. package/dist/components/SoftBuildersVideoPlayer/index.js +55 -0
  48. package/dist/components/SoftBuildersVideoPlayer/index.js.map +1 -0
  49. package/dist/components/SubtitleMenu/index.d.ts +4 -0
  50. package/dist/components/SubtitleMenu/index.js +54 -0
  51. package/dist/components/SubtitleMenu/index.js.map +1 -0
  52. package/dist/components/TimeSlider/index.d.ts +7 -0
  53. package/dist/components/TimeSlider/index.js +69 -0
  54. package/dist/components/TimeSlider/index.js.map +1 -0
  55. package/dist/components/TimeSliderContainer/index.d.ts +8 -0
  56. package/dist/components/TimeSliderContainer/index.js +14 -0
  57. package/dist/components/TimeSliderContainer/index.js.map +1 -0
  58. package/dist/components/Tooltip/index.d.ts +7 -0
  59. package/dist/components/Tooltip/index.js +8 -0
  60. package/dist/components/Tooltip/index.js.map +1 -0
  61. package/dist/components/VideoPlayerComponent/index.d.ts +17 -0
  62. package/dist/components/VideoPlayerComponent/index.js +140 -0
  63. package/dist/components/VideoPlayerComponent/index.js.map +1 -0
  64. package/dist/components/VideoPlayerComponent/provider.d.ts +18 -0
  65. package/dist/components/VideoPlayerComponent/provider.js +36 -0
  66. package/dist/components/VideoPlayerComponent/provider.js.map +1 -0
  67. package/dist/components/VideoPlayerComponent/style/style.css +36 -0
  68. package/dist/components/VolumeSlider/index.d.ts +4 -0
  69. package/dist/components/VolumeSlider/index.js +28 -0
  70. package/dist/components/VolumeSlider/index.js.map +1 -0
  71. package/dist/icons/index.d.ts +14 -0
  72. package/dist/icons/index.js +15 -0
  73. package/dist/icons/index.js.map +1 -0
  74. package/dist/index.d.ts +3 -0
  75. package/dist/index.js +3 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/styles/tailwind.css +778 -0
  78. package/dist/types.d.ts +33 -0
  79. package/dist/types.js +2 -0
  80. package/dist/types.js.map +1 -0
  81. package/dist/utils/index.d.ts +2 -0
  82. package/dist/utils/index.js +51 -0
  83. package/dist/utils/index.js.map +1 -0
  84. package/package.json +37 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 masri-softbuilders
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # Usage
2
+
3
+ ## install the package
4
+
5
+ ```bash
6
+ npm i soft-builders-video-player
7
+ ```
8
+
9
+ ## How to use
10
+
11
+ ```typescript
12
+ import SoftBuildersVideoPlayer, {
13
+ SoftBuildersVideoPlayerOptions,
14
+ SoftBuildersVideoPlayerChapter,
15
+ SoftBuildersVideoPlayerNote,
16
+ } from "soft-builders-video-player";
17
+
18
+ const options: SoftBuildersVideoPlayerOptions = {
19
+ autoplay: false,
20
+ controls: true,
21
+ muted: true,
22
+ fluid: true,
23
+ poster: "http://example.com/thumbnail.png", // thumbnail preview image
24
+ height: 420,
25
+ width: 720,
26
+ sources: [
27
+ {
28
+ src: "https://upload.wikimedia.org/wikipedia/commons/transcoded/a/ab/Caminandes_3_-_Llamigos_-_Blender_Animated_Short.webm/Caminandes_3_-_Llamigos_-_Blender_Animated_Short.webm.360p.vp9.webm",
29
+ type: "video/webm",
30
+ label: "360p",
31
+ },
32
+ {
33
+ src: "https://upload.wikimedia.org/wikipedia/commons/transcoded/a/ab/Caminandes_3_-_Llamigos_-_Blender_Animated_Short.webm/Caminandes_3_-_Llamigos_-_Blender_Animated_Short.webm.1080p.vp9.webm",
34
+ type: "video/webm",
35
+ label: "1080P",
36
+ },
37
+ ],
38
+ tracks: [
39
+ {
40
+ kind: "captions",
41
+ src: "https://raw.githubusercontent.com/brenopolanski/html5-video-webvtt-example/master/MIB2-subtitles-pt-BR.vtt",
42
+ srclang: "en",
43
+ label: "English",
44
+ memeType: "text/vtt", // text/vtt or text/srt
45
+ default: true,
46
+ },
47
+ {
48
+ kind: "captions",
49
+ src: "https://gist.githubusercontent.com/samdutton/ca37f3adaf4e23679957b8083e061177/raw/e19399fbccbc069a2af4266e5120ae6bad62699a/sample.vtt",
50
+ srclang: "es",
51
+ label: "Espaniol",
52
+ memeType: "text/vtt", // text/vtt or text/srt
53
+ },
54
+ ], // only vtt suptitilers are supported for now
55
+ };
56
+
57
+ const initNotes: SoftBuildersVideoPlayerNote[] = [
58
+ {
59
+ time: 5,
60
+ label: "Start",
61
+ },
62
+ {
63
+ time: 30,
64
+ label: "Say Hello",
65
+ },
66
+ {
67
+ time: 69,
68
+ label: "Go deep",
69
+ },
70
+ {
71
+ time: 99,
72
+ label: "Details ...",
73
+ },
74
+ {
75
+ time: 140,
76
+ label: "End",
77
+ },
78
+ ];
79
+
80
+ const initChapters: SoftBuildersVideoPlayerChapter[] = [
81
+ {
82
+ startTime: 25,
83
+ endTime: 50,
84
+ title: "01 Note: **** Important ****",
85
+ },
86
+ {
87
+ startTime: 70,
88
+ endTime: 100,
89
+ title: "02 Note: To Do",
90
+ },
91
+ { startTime: 110, endTime: 120, title: "03 Note: DIY (Do it yourself)" },
92
+ {
93
+ startTime: 125,
94
+ endTime: 140,
95
+ title: "05 Note: Conclusion ",
96
+ },
97
+ ];
98
+
99
+ const Component = () => {
100
+ const handleSaveNoteAction = (time: number, note: string) => {
101
+ return new Promise((resolve) => {
102
+ resolve(true);
103
+ });
104
+ };
105
+
106
+ const onPause = (time: number) => {
107
+ console.log(`Video has been Paused at time (${time} sec)`);
108
+ };
109
+ const onPlay = (time: number) => {
110
+ console.log(`Video has been Played at time (${time} sec)`);
111
+ };
112
+
113
+ return (
114
+ <SoftBuildersVideoPlayer
115
+ options={options}
116
+ chapters={initChapters}
117
+ notes={initNotes}
118
+ handleSaveNoteAction={handleSaveNoteAction}
119
+ onPause={onPause}
120
+ onPlay={onPlay}
121
+ />
122
+ );
123
+ };
124
+
125
+ export default Component;
126
+ ```
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import Player from "video.js/dist/types/player";
3
+ type Props = {
4
+ player: Player | undefined;
5
+ isPaused: boolean;
6
+ setIsPaused: React.Dispatch<React.SetStateAction<boolean>>;
7
+ };
8
+ declare const BigPlayButton: ({ player, isPaused, setIsPaused }: Props) => React.JSX.Element;
9
+ export default BigPlayButton;
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+ import { PauseIcon, PlayIcon } from "../../icons";
3
+ const BigPlayButton = ({ player, isPaused, setIsPaused }) => {
4
+ const togglePlay = () => {
5
+ if (isPaused)
6
+ player === null || player === void 0 ? void 0 : player.play();
7
+ else
8
+ player === null || player === void 0 ? void 0 : player.pause();
9
+ setIsPaused(!isPaused);
10
+ };
11
+ return (React.createElement("button", { onClick: togglePlay },
12
+ React.createElement("div", { className: "sb-w-16 sb-h-16 sb-rounded-full sb-bg-white/30 sb-backdrop-blur-lg sb-flex sb-items-center sb-justify-center " }, isPaused ? (React.createElement(PlayIcon, { className: "sb-w-4 sb-h-4" })) : (React.createElement(PauseIcon, { className: "sb-w-4 sb-h-4" })))));
13
+ };
14
+ export default BigPlayButton;
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/BigPlayButton/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAOlD,MAAM,aAAa,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAS,EAAE,EAAE;IACjE,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,QAAQ;YAAE,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,EAAE,CAAC;;YACxB,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,EAAE,CAAC;QAErB,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC,CAAC;IAEF,OAAO,CACL,gCAAQ,OAAO,EAAE,UAAU;QACzB,6BAAK,SAAS,EAAC,+GAA+G,IAC3H,QAAQ,CAAC,CAAC,CAAC,CACV,oBAAC,QAAQ,IAAC,SAAS,EAAC,eAAe,GAAG,CACvC,CAAC,CAAC,CAAC,CACF,oBAAC,SAAS,IAAC,SAAS,EAAC,eAAe,GAAG,CACxC,CACG,CACC,CACV,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ declare const BufferTracker: () => React.JSX.Element;
3
+ export default BufferTracker;
@@ -0,0 +1,16 @@
1
+ import React, { useEffect } from "react";
2
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
3
+ const BufferTracker = () => {
4
+ const { player, setDownloadedBufferTimeufferTime } = useSoftBuildersVideoPlayerContext();
5
+ useEffect(() => {
6
+ const intervalId = setInterval(() => {
7
+ if (player)
8
+ setDownloadedBufferTimeufferTime(player.bufferedEnd());
9
+ }, 1000);
10
+ // Cleanup function to clear the interval
11
+ return () => clearInterval(intervalId);
12
+ }, [player]);
13
+ return React.createElement(React.Fragment, null);
14
+ };
15
+ export default BufferTracker;
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/BufferTracker/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AAErF,MAAM,aAAa,GAAG,GAAG,EAAE;IACzB,MAAM,EAAE,MAAM,EAAE,gCAAgC,EAAE,GAChD,iCAAiC,EAAE,CAAC;IAEtC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;YAClC,IAAI,MAAM;gBAAE,gCAAgC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QACrE,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,yCAAyC;QACzC,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACb,OAAO,yCAAK,CAAC;AACf,CAAC,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { SoftBuildersVideoPlayerChapter } from "../../types";
3
+ type Chapter = SoftBuildersVideoPlayerChapter & {
4
+ startPercentage: number;
5
+ endPercentage: number;
6
+ };
7
+ type Props = {
8
+ chapter: Chapter;
9
+ };
10
+ declare const ChapterTooltip: ({ chapter }: Props) => React.JSX.Element;
11
+ export default ChapterTooltip;
@@ -0,0 +1,36 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import Tooltip from "../Tooltip";
3
+ import { durationFormater } from "../../utils";
4
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
5
+ const ChapterTooltip = ({ chapter }) => {
6
+ const { player } = useSoftBuildersVideoPlayerContext();
7
+ const [open, setOpen] = useState(false);
8
+ const { currentTime } = useSoftBuildersVideoPlayerContext();
9
+ useEffect(() => {
10
+ if (currentTime === Math.floor(chapter.startTime)) {
11
+ setOpen(true);
12
+ setTimeout(() => {
13
+ setOpen(false);
14
+ }, 5000);
15
+ }
16
+ }, [currentTime, chapter.startTime]);
17
+ const handleClickChapter = () => {
18
+ player === null || player === void 0 ? void 0 : player.currentTime(chapter.startTime);
19
+ };
20
+ return (React.createElement("div", { id: `ii-section-${chapter.title}`, className: "sb-flex sb-items-center sb-w-full sb-h-full sb-absolute sb-z-20", style: {
21
+ left: `${chapter.startPercentage}%`,
22
+ width: `${chapter.endPercentage - chapter.startPercentage}%`,
23
+ }, onMouseEnter: () => setOpen(true), onMouseLeave: () => setOpen(false) },
24
+ React.createElement("button", { id: `section-${chapter.title}`, className: "sb-h-full sb-w-full", onClick: handleClickChapter },
25
+ React.createElement("div", { className: "sb-relative sb-flex sb-h-full sb-w-full sb-justify-between sb-items-center" },
26
+ React.createElement(Tooltip, { open: open },
27
+ React.createElement("div", { className: "sb-flex sb-flex-col sb-gap-2 sb-items-center" },
28
+ React.createElement("p", null, chapter.title),
29
+ React.createElement("p", { className: "sb-p-2 sb-bg-[#303030] sb-bg-opacity-50 sb-rounded-md" },
30
+ durationFormater(chapter.startTime),
31
+ " -",
32
+ " ",
33
+ durationFormater(chapter.endTime))))))));
34
+ };
35
+ export default ChapterTooltip;
36
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ChapterTooltip/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,OAAO,MAAM,YAAY,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AAQrF,MAAM,cAAc,GAAG,CAAC,EAAE,OAAO,EAAS,EAAE,EAAE;IAC5C,MAAM,EAAE,MAAM,EAAE,GAAG,iCAAiC,EAAE,CAAC;IAEvD,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,EAAE,WAAW,EAAE,GAAG,iCAAiC,EAAE,CAAC;IAE5D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,WAAW,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAClD,OAAO,CAAC,IAAI,CAAC,CAAC;YAEd,UAAU,CAAC,GAAG,EAAE;gBACd,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC,EAAE,IAAI,CAAC,CAAC;QACX,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAErC,MAAM,kBAAkB,GAAG,GAAG,EAAE;QAC9B,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC,CAAC;IAEF,OAAO,CACL,6BACE,EAAE,EAAE,cAAc,OAAO,CAAC,KAAK,EAAE,EACjC,SAAS,EAAC,iEAAiE,EAC3E,KAAK,EAAE;YACL,IAAI,EAAE,GAAG,OAAO,CAAC,eAAe,GAAG;YACnC,KAAK,EAAE,GAAG,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC,eAAe,GAAG;SAC7D,EACD,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EACjC,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;QAElC,gCACE,EAAE,EAAE,WAAW,OAAO,CAAC,KAAK,EAAE,EAC9B,SAAS,EAAC,qBAAqB,EAC/B,OAAO,EAAE,kBAAkB;YAE3B,6BAAK,SAAS,EAAC,4EAA4E;gBACzF,oBAAC,OAAO,IAAC,IAAI,EAAE,IAAI;oBACjB,6BAAK,SAAS,EAAC,8CAA8C;wBAC3D,+BAAI,OAAO,CAAC,KAAK,CAAK;wBACtB,2BAAG,SAAS,EAAC,uDAAuD;4BACjE,gBAAgB,CAAC,OAAO,CAAC,SAAS,CAAC;;4BAAI,GAAG;4BAC1C,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,CAChC,CACA,CACE,CACN,CACC,CACL,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ import { SoftBuildersVideoPlayerChapter } from "../../types";
3
+ type Props = {
4
+ chapters: SoftBuildersVideoPlayerChapter[];
5
+ };
6
+ declare const ChaptersPanal: ({ chapters }: Props) => React.JSX.Element;
7
+ export default ChaptersPanal;
@@ -0,0 +1,19 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import ChapterTooltip from "../ChapterTooltip";
3
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
4
+ const ChaptersPanal = ({ chapters }) => {
5
+ const [cs, setCs] = useState([]);
6
+ const { duration } = useSoftBuildersVideoPlayerContext();
7
+ useEffect(() => {
8
+ const newCs = chapters.map((c) => {
9
+ const startPercentage = Math.floor((c.startTime * 100) / duration);
10
+ const endPercentage = Math.floor((c.endTime * 100) / duration);
11
+ return Object.assign(Object.assign({}, c), { startPercentage,
12
+ endPercentage });
13
+ });
14
+ setCs(newCs);
15
+ }, [chapters, duration]);
16
+ return (React.createElement("div", { id: "chapters-panal", className: "sb-w-full sb-h-full sb-relative " }, cs.map((c, i) => (React.createElement(ChapterTooltip, { key: `chapter-${i}-${c.startTime}`, chapter: c })))));
17
+ };
18
+ export default ChaptersPanal;
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ChaptersPanal/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAE/C,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AASrF,MAAM,aAAa,GAAG,CAAC,EAAE,QAAQ,EAAS,EAAE,EAAE;IAC5C,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,QAAQ,CAAY,EAAE,CAAC,CAAC;IAC5C,MAAM,EAAE,QAAQ,EAAE,GAAG,iCAAiC,EAAE,CAAC;IAEzD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC/B,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;YACnE,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;YAC/D,uCACK,CAAC,KACJ,eAAe;gBACf,aAAa,IACb;QACJ,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,CAAC,CAAC;IACf,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEzB,OAAO,CACL,6BAAK,EAAE,EAAC,gBAAgB,EAAC,SAAS,EAAC,kCAAkC,IAClE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAChB,oBAAC,cAAc,IAAC,GAAG,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,GAAI,CACnE,CAAC,CACE,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+ import Player from "video.js/dist/types/player";
3
+ import { SoftBuildersVideoPlayerChapter, SoftBuildersVideoPlayerNote } from "../../types";
4
+ type Props<T> = {
5
+ player: Player | undefined;
6
+ isPaused: boolean;
7
+ setIsPaused: React.Dispatch<React.SetStateAction<boolean>>;
8
+ duration: number;
9
+ notes: SoftBuildersVideoPlayerNote[];
10
+ chapters: SoftBuildersVideoPlayerChapter[];
11
+ seekStep?: number;
12
+ handleSaveNoteAction?: (time: number, note: string) => Promise<T>;
13
+ };
14
+ declare const ControlBar: <T>({ player, isPaused, setIsPaused, duration, notes, chapters, seekStep, handleSaveNoteAction, }: Props<T>) => React.JSX.Element;
15
+ export default ControlBar;
@@ -0,0 +1,64 @@
1
+ import React, { useEffect } from "react";
2
+ import CurrentTimeLabel from "../CurrentTimeLabel";
3
+ import { durationFormater } from "../../utils";
4
+ import VolumeSlider from "../VolumeSlider";
5
+ import QualityMenu from "../QualityMenu";
6
+ import CreateNoteMenu from "../CreateNoteMenu";
7
+ import { BackwardIcon, PlayIcon, PauseIcon, ForwardIcon, FullScreenIcon, } from "../../icons";
8
+ import TimeSliderContainer from "../TimeSliderContainer";
9
+ import BufferTracker from "../BufferTracker";
10
+ import CurrentTimeTracker from "../CurrentTimeTracker";
11
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
12
+ import SubtitleMenu from "../SubtitleMenu";
13
+ const ControlBar = ({ player, isPaused, setIsPaused, duration, notes, chapters, seekStep = 5, handleSaveNoteAction, }) => {
14
+ const { setPlayer, setDuration } = useSoftBuildersVideoPlayerContext();
15
+ const seek = (duration) => {
16
+ const currentTime = Number((player === null || player === void 0 ? void 0 : player.currentTime()) || 0);
17
+ player === null || player === void 0 ? void 0 : player.currentTime(currentTime + duration);
18
+ };
19
+ const togglePlay = () => {
20
+ if (isPaused)
21
+ player === null || player === void 0 ? void 0 : player.play();
22
+ else
23
+ player === null || player === void 0 ? void 0 : player.pause();
24
+ setIsPaused(!isPaused);
25
+ };
26
+ useEffect(() => {
27
+ setPlayer(player);
28
+ }, [player]);
29
+ useEffect(() => {
30
+ setDuration(duration);
31
+ }, [duration]);
32
+ return (React.createElement("div", { className: "sb-flex sb-items-center sb-justify-center sb-gap-3 sb-w-full" },
33
+ React.createElement(BufferTracker, null),
34
+ React.createElement(CurrentTimeTracker, null),
35
+ React.createElement("button", { onClick: () => {
36
+ seek(-seekStep);
37
+ } },
38
+ React.createElement(BackwardIcon, { className: "sb-w-3 sb-h-3" })),
39
+ React.createElement("button", { onClick: togglePlay }, isPaused ? (React.createElement(PlayIcon, { className: "sb-w-3 sb-h-3" })) : (React.createElement(PauseIcon, { className: "sb-w-3 sb-h-3" }))),
40
+ React.createElement("button", { onClick: () => {
41
+ seek(seekStep);
42
+ } },
43
+ React.createElement(ForwardIcon, { className: "sb-w-3 sb-h-3" })),
44
+ React.createElement(CurrentTimeLabel, null),
45
+ React.createElement("div", { className: "sb-w-[30%] hover:sb-w-[45%] sb-transition-all sb-ease-in-out sb-duration-500" },
46
+ React.createElement(TimeSliderContainer, { chapters: chapters, notes: notes })),
47
+ React.createElement("p", null, durationFormater(duration)),
48
+ React.createElement("div", { className: "sb-w-[10%]" },
49
+ React.createElement(VolumeSlider, null)),
50
+ React.createElement(QualityMenu, null),
51
+ React.createElement("button", { onClick: () => {
52
+ if (player === null || player === void 0 ? void 0 : player.isFullscreen()) {
53
+ player === null || player === void 0 ? void 0 : player.exitFullscreen();
54
+ }
55
+ else {
56
+ player === null || player === void 0 ? void 0 : player.requestFullscreen();
57
+ }
58
+ } },
59
+ React.createElement(FullScreenIcon, { className: "sb-w-3 sb-h-3" })),
60
+ handleSaveNoteAction && (React.createElement(CreateNoteMenu, { handleSaveNoteAction: handleSaveNoteAction })),
61
+ React.createElement(SubtitleMenu, null)));
62
+ };
63
+ export default ControlBar;
64
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ControlBar/index.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ type Props<T> = {
3
+ handleSaveNoteAction?: (time: number, note: string) => Promise<T>;
4
+ };
5
+ declare const CreateNoteMenu: <T>({ handleSaveNoteAction }: Props<T>) => React.JSX.Element;
6
+ export default CreateNoteMenu;
@@ -0,0 +1,29 @@
1
+ import React, { useState } from "react";
2
+ import MenuButton from "../MenuButton";
3
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
4
+ import { ClosedNoteIcon } from "../../icons";
5
+ const CreateNoteMenu = ({ handleSaveNoteAction }) => {
6
+ const { player } = useSoftBuildersVideoPlayerContext();
7
+ const [note, setNote] = useState("");
8
+ const handleSaveNote = () => {
9
+ if (handleSaveNoteAction) {
10
+ const time = (player === null || player === void 0 ? void 0 : player.currentTime()) || 0;
11
+ handleSaveNoteAction(time, note).then((response) => {
12
+ setNote("");
13
+ });
14
+ }
15
+ else {
16
+ window.alert("Video Player, there is no implementation for the handleSaveNoteAction function");
17
+ }
18
+ };
19
+ return (React.createElement(MenuButton, { buttonContent: React.createElement(ClosedNoteIcon, { className: "sb-w-3 sb-h-3" }), menuContent: React.createElement("div", { className: "sb-rounded-md sb-bg-[#303030] sb-bg-opacity-50 sb-py-5 sb-w-[220px]" },
20
+ React.createElement("div", { className: "sb-flex sb-flex-col sb-gap-3" },
21
+ React.createElement("h3", { className: "sb-px-5" }, "Add Note"),
22
+ React.createElement("div", { className: "sb-w-full sb-h-[.1px] sb-bg-[#AAAAAA] sb-bg-opacity-70" }),
23
+ React.createElement("div", { className: "sb-px-5 sb-flex sb-flex-col sb-gap-4 sb-items-start" },
24
+ React.createElement("input", { name: "note", type: "text", placeholder: "Add a note", value: note, onChange: (e) => setNote(e.target.value), required: true, className: "sb-text-white placeholder:sb-text-white sb-w-full sb-bg-transparent sb-px-4 sb-py-3 sb-border sb-border-[#AAAAAA] sb-rounded-md" }),
25
+ React.createElement("button", { className: "sb-w-full", onClick: handleSaveNote },
26
+ React.createElement("div", { className: "sb-px-4 sb-py-3 sb-text-center sb-font-bold sb-bg-orange-500 sb-rounded-md" }, "Save"))))) }));
27
+ };
28
+ export default CreateNoteMenu;
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/CreateNoteMenu/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,UAAU,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AAErF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAK7C,MAAM,cAAc,GAAG,CAAK,EAAE,oBAAoB,EAAY,EAAE,EAAE;IAChE,MAAM,EAAE,MAAM,EAAE,GAAG,iCAAiC,EAAE,CAAC;IAEvD,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAErC,MAAM,cAAc,GAAG,GAAG,EAAE;QAC1B,IAAI,oBAAoB,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,WAAW,EAAE,KAAI,CAAC,CAAC;YACxC,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;gBACjD,OAAO,CAAC,EAAE,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CACV,gFAAgF,CACjF,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CACL,oBAAC,UAAU,IACT,aAAa,EAAE,oBAAC,cAAc,IAAC,SAAS,EAAC,eAAe,GAAG,EAC3D,WAAW,EACT,6BAAK,SAAS,EAAC,qEAAqE;YAClF,6BAAK,SAAS,EAAC,8BAA8B;gBAC3C,4BAAI,SAAS,EAAC,SAAS,eAAc;gBAErC,6BAAK,SAAS,EAAC,wDAAwD,GAAG;gBAE1E,6BAAK,SAAS,EAAC,qDAAqD;oBAClE,+BACE,IAAI,EAAC,MAAM,EACX,IAAI,EAAC,MAAM,EACX,WAAW,EAAC,YAAY,EACxB,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACxC,QAAQ,QACR,SAAS,EAAC,iIAAiI,GAC3I;oBAEF,gCAAQ,SAAS,EAAC,WAAW,EAAC,OAAO,EAAE,cAAc;wBACnD,6BAAK,SAAS,EAAC,4EAA4E,WAErF,CACC,CACL,CACF,CACF,GAER,CACH,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ type Props = {};
3
+ declare const CurrentTimeLabel: ({}: Props) => React.JSX.Element;
4
+ export default CurrentTimeLabel;
@@ -0,0 +1,10 @@
1
+ "use client";
2
+ import React from "react";
3
+ import { durationFormater } from "../../utils";
4
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
5
+ const CurrentTimeLabel = ({}) => {
6
+ const { currentTime } = useSoftBuildersVideoPlayerContext();
7
+ return React.createElement("p", null, durationFormater(currentTime));
8
+ };
9
+ export default CurrentTimeLabel;
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/CurrentTimeLabel/index.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb,OAAO,KAAoB,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AAGrF,MAAM,gBAAgB,GAAG,CAAC,EAAS,EAAE,EAAE;IACrC,MAAM,EAAE,WAAW,EAAE,GAAG,iCAAiC,EAAE,CAAC;IAE5D,OAAO,+BAAI,gBAAgB,CAAC,WAAW,CAAC,CAAK,CAAC;AAChD,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import React from "react";
2
+ declare const CurrentTimeTracker: () => React.JSX.Element;
3
+ export default CurrentTimeTracker;
@@ -0,0 +1,15 @@
1
+ import React, { useEffect } from "react";
2
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
3
+ const CurrentTimeTracker = () => {
4
+ const { setCurrentTime, player } = useSoftBuildersVideoPlayerContext();
5
+ useEffect(() => {
6
+ const intervalId = setInterval(() => {
7
+ setCurrentTime((player === null || player === void 0 ? void 0 : player.currentTime()) || 0);
8
+ }, 500);
9
+ // Cleanup function to clear the interval
10
+ return () => clearInterval(intervalId);
11
+ }, [player]);
12
+ return React.createElement(React.Fragment, null);
13
+ };
14
+ export default CurrentTimeTracker;
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/CurrentTimeTracker/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AAErF,MAAM,kBAAkB,GAAG,GAAG,EAAE;IAC9B,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,iCAAiC,EAAE,CAAC;IAEvE,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;YAClC,cAAc,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,WAAW,EAAE,KAAI,CAAC,CAAC,CAAC;QAC7C,CAAC,EAAE,GAAG,CAAC,CAAC;QAER,yCAAyC;QACzC,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACb,OAAO,yCAAK,CAAC;AACf,CAAC,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ type Props = {
3
+ name: string;
4
+ };
5
+ declare const Menu: ({ name }: Props) => React.JSX.Element;
6
+ export default Menu;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ const Menu = ({ name }) => {
3
+ return (React.createElement("div", { className: "absolute right-0 z-10 w-48 mt-2 origin-top-right bg-white border border-gray-300 rounded-md shadow-lg focus:outline-none" },
4
+ React.createElement("div", { className: "py-1", role: "menu", "aria-orientation": "vertical", "aria-labelledby": `${name}-button` },
5
+ React.createElement("a", { href: "#", className: "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900", role: "menuitem" }, "Dashboard"),
6
+ React.createElement("a", { href: "#", className: "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900", role: "menuitem" }, "Settings"),
7
+ React.createElement("a", { href: "#", className: "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900", role: "menuitem" }, "Profile"),
8
+ React.createElement("a", { href: "#", className: "block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900", role: "menuitem" }, "Logout"))));
9
+ };
10
+ export default Menu;
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/Menu/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,MAAM,IAAI,GAAG,CAAC,EAAE,IAAI,EAAS,EAAE,EAAE;IAC/B,OAAO,CACL,6BAAK,SAAS,EAAC,0HAA0H;QACvI,6BACE,SAAS,EAAC,MAAM,EAChB,IAAI,EAAC,MAAM,sBACM,UAAU,qBACV,GAAG,IAAI,SAAS;YAEjC,2BACE,IAAI,EAAC,GAAG,EACR,SAAS,EAAC,6EAA6E,EACvF,IAAI,EAAC,UAAU,gBAGb;YACJ,2BACE,IAAI,EAAC,GAAG,EACR,SAAS,EAAC,6EAA6E,EACvF,IAAI,EAAC,UAAU,eAGb;YACJ,2BACE,IAAI,EAAC,GAAG,EACR,SAAS,EAAC,6EAA6E,EACvF,IAAI,EAAC,UAAU,cAGb;YACJ,2BACE,IAAI,EAAC,GAAG,EACR,SAAS,EAAC,6EAA6E,EACvF,IAAI,EAAC,UAAU,aAGb,CACA,CACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ type Props = {
3
+ buttonContent: React.ReactNode;
4
+ menuContent: React.ReactNode;
5
+ close?: (fun: Function) => void;
6
+ };
7
+ declare const MenuButton: ({ buttonContent, menuContent, close }: Props) => React.JSX.Element;
8
+ export default MenuButton;
@@ -0,0 +1,31 @@
1
+ import React, { useCallback, useEffect, useRef, useState } from "react";
2
+ const MenuButton = ({ buttonContent, menuContent, close }) => {
3
+ const [isOpen, setIsOpen] = useState(false);
4
+ const buttonRef = useRef(null);
5
+ const menuRef = useRef(null);
6
+ const toggleMenu = () => setIsOpen((prev) => !prev);
7
+ const closeMenu = useCallback(() => {
8
+ setIsOpen(false);
9
+ }, []);
10
+ useEffect(() => {
11
+ const handleClickOutside = (event) => {
12
+ if (buttonRef.current &&
13
+ !buttonRef.current.contains(event.target) &&
14
+ menuRef.current &&
15
+ !menuRef.current.contains(event.target)) {
16
+ setIsOpen(false);
17
+ }
18
+ };
19
+ document.addEventListener("mousedown", handleClickOutside);
20
+ return () => document.removeEventListener("mousedown", handleClickOutside);
21
+ }, []);
22
+ useEffect(() => {
23
+ if (close)
24
+ close(closeMenu);
25
+ }, [close, closeMenu]);
26
+ return (React.createElement("div", { className: "sb-relative" },
27
+ React.createElement("button", { ref: buttonRef, onClick: toggleMenu, "aria-haspopup": "true", "aria-expanded": isOpen, "aria-label": "Open menu" }, buttonContent),
28
+ isOpen && (React.createElement("div", { ref: menuRef, role: "menu", "aria-orientation": "vertical", "aria-labelledby": "Open menu", className: "sb-absolute sb-shadow-lg sb-right-0 sb-bottom-10" }, menuContent))));
29
+ };
30
+ export default MenuButton;
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/MenuButton/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAQxE,MAAM,UAAU,GAAG,CAAC,EAAE,aAAa,EAAE,WAAW,EAAE,KAAK,EAAS,EAAE,EAAE;IAClE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,MAAM,CAA2B,IAAI,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IAEpD,MAAM,UAAU,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAEpD,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;QACjC,SAAS,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,kBAAkB,GAAG,CAAC,KAAiB,EAAE,EAAE;YAC/C,IACE,SAAS,CAAC,OAAO;gBACjB,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAc,CAAC;gBACjD,OAAO,CAAC,OAAO;gBACf,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAc,CAAC,EAC/C,CAAC;gBACD,SAAS,CAAC,KAAK,CAAC,CAAC;YACnB,CAAC;QACH,CAAC,CAAC;QAEF,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;QAC3D,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;IAC7E,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,KAAK;YAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAEvB,OAAO,CACL,6BAAK,SAAS,EAAC,aAAa;QAC1B,gCACE,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,UAAU,mBACL,MAAM,mBACL,MAAM,gBACV,WAAW,IAErB,aAAa,CACP;QAER,MAAM,IAAI,CACT,6BACE,GAAG,EAAE,OAAO,EACZ,IAAI,EAAC,MAAM,sBACM,UAAU,qBACX,WAAW,EAC3B,SAAS,EAAC,kDAAkD,IAE3D,WAAW,CACR,CACP,CACG,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { SoftBuildersVideoPlayerNote } from "../../types";
3
+ type Note = SoftBuildersVideoPlayerNote & {
4
+ percentage: number;
5
+ };
6
+ type Props = {
7
+ note: Note;
8
+ };
9
+ declare const NoteTooltip: ({ note }: Props) => React.JSX.Element;
10
+ export default NoteTooltip;
@@ -0,0 +1,24 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import Tooltip from "../Tooltip";
3
+ import { durationFormater } from "../../utils";
4
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
5
+ const NoteTooltip = ({ note }) => {
6
+ const [open, setOpen] = useState(false);
7
+ const { currentTime } = useSoftBuildersVideoPlayerContext();
8
+ useEffect(() => {
9
+ if (currentTime === Math.floor(note.time)) {
10
+ setOpen(true);
11
+ setTimeout(() => {
12
+ setOpen(false);
13
+ }, 5000);
14
+ }
15
+ }, [currentTime, note.time]);
16
+ return (React.createElement("div", { className: "sb-w-1 sb-h-1 sb-rounded-full sb-bg-white sb-absolute sb-z-30", style: { left: `${note.percentage}%` }, onMouseEnter: () => setOpen(true), onMouseLeave: () => setOpen(false) },
17
+ React.createElement("div", { className: "sb-relative" },
18
+ React.createElement(Tooltip, { open: open },
19
+ React.createElement("div", { className: "sb-flex sb-flex-col sb-gap-2 sb-items-center" },
20
+ React.createElement("p", null, note.label),
21
+ React.createElement("p", { className: "sb-p-2 sb-bg-[#303030] sb-bg-opacity-50 sb-rounded-md" }, durationFormater(note.time)))))));
22
+ };
23
+ export default NoteTooltip;
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/NoteTooltip/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,OAAO,MAAM,YAAY,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AAQrF,MAAM,WAAW,GAAG,CAAC,EAAE,IAAI,EAAS,EAAE,EAAE;IACtC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,EAAE,WAAW,EAAE,GAAG,iCAAiC,EAAE,CAAC;IAE5D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,WAAW,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,CAAC;YAEd,UAAU,CAAC,GAAG,EAAE;gBACd,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC,EAAE,IAAI,CAAC,CAAC;QACX,CAAC;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7B,OAAO,CACL,6BACE,SAAS,EAAC,+DAA+D,EACzE,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,UAAU,GAAG,EAAE,EACtC,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EACjC,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;QAElC,6BAAK,SAAS,EAAC,aAAa;YAC1B,oBAAC,OAAO,IAAC,IAAI,EAAE,IAAI;gBACjB,6BAAK,SAAS,EAAC,8CAA8C;oBAC3D,+BAAI,IAAI,CAAC,KAAK,CAAK;oBACnB,2BAAG,SAAS,EAAC,uDAAuD,IACjE,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAC1B,CACA,CACE,CACN,CACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ import { SoftBuildersVideoPlayerNote } from "../../types";
3
+ type Props = {
4
+ notes: SoftBuildersVideoPlayerNote[];
5
+ };
6
+ declare const NotesPanal: ({ notes }: Props) => React.JSX.Element;
7
+ export default NotesPanal;
@@ -0,0 +1,17 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import NoteTooltip from "../NoteTooltip";
3
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
4
+ const NotesPanal = ({ notes }) => {
5
+ const [ns, setNs] = useState([]);
6
+ const { duration } = useSoftBuildersVideoPlayerContext();
7
+ useEffect(() => {
8
+ const newNs = notes.map((n) => {
9
+ const percentage = Math.floor((n.time * 100) / duration);
10
+ return Object.assign(Object.assign({}, n), { percentage });
11
+ });
12
+ setNs(newNs);
13
+ }, [notes, duration]);
14
+ return (React.createElement("div", { id: "notes-panal", className: "sb-w-full sb-h-full sb-relative " }, ns.map((n, i) => (React.createElement(NoteTooltip, { key: `note-${i}-${n.time}`, note: n })))));
15
+ };
16
+ export default NotesPanal;
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/NotesPanal/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,WAAW,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,iCAAiC,EAAE,MAAM,kCAAkC,CAAC;AAOrF,MAAM,UAAU,GAAG,CAAC,EAAE,KAAK,EAAS,EAAE,EAAE;IACtC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IAEzC,MAAM,EAAE,QAAQ,EAAE,GAAG,iCAAiC,EAAE,CAAC;IAEzD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;YACzD,uCACK,CAAC,KACJ,UAAU,IACV;QACJ,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,CAAC,CAAC;IACf,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IACtB,OAAO,CACL,6BAAK,EAAE,EAAC,aAAa,EAAC,SAAS,EAAC,kCAAkC,IAC/D,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAChB,oBAAC,WAAW,IAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,GAAI,CACrD,CAAC,CACE,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,UAAU,CAAC"}