softbuilders-react-video-player 1.1.14 → 1.1.16

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.
Files changed (29) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +126 -126
  3. package/dist/components/BufferTracker/index.tsx +19 -19
  4. package/dist/components/ChapterTooltip/index.tsx +65 -65
  5. package/dist/components/ChaptersPanal/index.tsx +40 -40
  6. package/dist/components/ControlBar/index.js +1 -2
  7. package/dist/components/ControlBar/index.js.map +1 -1
  8. package/dist/components/ControlBar/index.tsx +3 -4
  9. package/dist/components/CreateNoteMenu/index.tsx +61 -61
  10. package/dist/components/CurrentTimeLabel/index.tsx +13 -13
  11. package/dist/components/CurrentTimeTracker/index.tsx +18 -18
  12. package/dist/components/Menu/index.tsx +49 -49
  13. package/dist/components/NoteTooltip/index.tsx +46 -46
  14. package/dist/components/NotesPanal/index.tsx +34 -34
  15. package/dist/components/TimeSlider/index.js +13 -13
  16. package/dist/components/TimeSlider/index.tsx +107 -107
  17. package/dist/components/TimeSliderContainer/index.tsx +35 -35
  18. package/dist/components/Tooltip/index.tsx +16 -16
  19. package/dist/components/VideoPlayerComponent/index.js +1 -1
  20. package/dist/components/VideoPlayerComponent/index.js.map +1 -1
  21. package/dist/components/VideoPlayerComponent/index.tsx +2 -33
  22. package/dist/components/VideoPlayerComponent/provider.tsx +82 -82
  23. package/dist/components/VideoPlayerComponent/style/style.css +36 -36
  24. package/dist/components/VolumeSlider/index.js +1 -1
  25. package/dist/components/VolumeSlider/index.js.map +1 -1
  26. package/dist/components/VolumeSlider/index.tsx +2 -12
  27. package/dist/index.mjs +3 -4
  28. package/dist/styles/tailwind.css +101 -101
  29. package/package.json +1 -1
@@ -1,61 +1,61 @@
1
- import React, { useState } from "react";
2
- import MenuButton from "../MenuButton";
3
- import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
4
- import { ClosedNoteIcon } from "../../images";
5
-
6
- type Props<T> = {
7
- handleSaveNoteAction?: (time: number, note: string) => Promise<T>;
8
- };
9
- const CreateNoteMenu = <T,>({ handleSaveNoteAction }: Props<T>) => {
10
- const { player } = useSoftBuildersVideoPlayerContext();
11
-
12
- const [note, setNote] = useState("");
13
-
14
- const handleSaveNote = () => {
15
- if (handleSaveNoteAction) {
16
- const time = player?.currentTime() || 0;
17
- handleSaveNoteAction(time, note).then((response) => {
18
- setNote("");
19
- });
20
- } else {
21
- window.alert(
22
- "Video Player, there is no implementation for the handleSaveNoteAction function"
23
- );
24
- }
25
- };
26
-
27
- return (
28
- <MenuButton
29
- buttonContent={<ClosedNoteIcon className="sb-w-3 sb-h-3" />}
30
- menuContent={
31
- <div className="sb-rounded-md sb-bg-[#303030] sb-bg-opacity-50 sb-py-5 sb-w-[220px]">
32
- <div className="sb-flex sb-flex-col sb-gap-3">
33
- <h3 className="sb-px-5">Add Note</h3>
34
-
35
- <div className="sb-w-full sb-h-[.1px] sb-bg-[#AAAAAA] sb-bg-opacity-70" />
36
-
37
- <div className="sb-px-5 sb-flex sb-flex-col sb-gap-4 sb-items-start">
38
- <input
39
- name="note"
40
- type="text"
41
- placeholder="Add a note"
42
- value={note}
43
- onChange={(e) => setNote(e.target.value)}
44
- required
45
- 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"
46
- />
47
-
48
- <button className="sb-w-full" onClick={handleSaveNote}>
49
- <div className="sb-px-4 sb-py-3 sb-text-center sb-font-bold sb-bg-orange-500 sb-rounded-md">
50
- Save
51
- </div>
52
- </button>
53
- </div>
54
- </div>
55
- </div>
56
- }
57
- />
58
- );
59
- };
60
-
61
- export default CreateNoteMenu;
1
+ import React, { useState } from "react";
2
+ import MenuButton from "../MenuButton";
3
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
4
+ import { ClosedNoteIcon } from "../../images";
5
+
6
+ type Props<T> = {
7
+ handleSaveNoteAction?: (time: number, note: string) => Promise<T>;
8
+ };
9
+ const CreateNoteMenu = <T,>({ handleSaveNoteAction }: Props<T>) => {
10
+ const { player } = useSoftBuildersVideoPlayerContext();
11
+
12
+ const [note, setNote] = useState("");
13
+
14
+ const handleSaveNote = () => {
15
+ if (handleSaveNoteAction) {
16
+ const time = player?.currentTime() || 0;
17
+ handleSaveNoteAction(time, note).then((response) => {
18
+ setNote("");
19
+ });
20
+ } else {
21
+ window.alert(
22
+ "Video Player, there is no implementation for the handleSaveNoteAction function"
23
+ );
24
+ }
25
+ };
26
+
27
+ return (
28
+ <MenuButton
29
+ buttonContent={<ClosedNoteIcon className="sb-w-3 sb-h-3" />}
30
+ menuContent={
31
+ <div className="sb-rounded-md sb-bg-[#303030] sb-bg-opacity-50 sb-py-5 sb-w-[220px]">
32
+ <div className="sb-flex sb-flex-col sb-gap-3">
33
+ <h3 className="sb-px-5">Add Note</h3>
34
+
35
+ <div className="sb-w-full sb-h-[.1px] sb-bg-[#AAAAAA] sb-bg-opacity-70" />
36
+
37
+ <div className="sb-px-5 sb-flex sb-flex-col sb-gap-4 sb-items-start">
38
+ <input
39
+ name="note"
40
+ type="text"
41
+ placeholder="Add a note"
42
+ value={note}
43
+ onChange={(e) => setNote(e.target.value)}
44
+ required
45
+ 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"
46
+ />
47
+
48
+ <button className="sb-w-full" onClick={handleSaveNote}>
49
+ <div className="sb-px-4 sb-py-3 sb-text-center sb-font-bold sb-bg-orange-500 sb-rounded-md">
50
+ Save
51
+ </div>
52
+ </button>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ }
57
+ />
58
+ );
59
+ };
60
+
61
+ export default CreateNoteMenu;
@@ -1,13 +1,13 @@
1
- "use client";
2
- import React, { useEffect } from "react";
3
- import { durationFormater } from "../../utils";
4
- import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
5
- type Props = {};
6
-
7
- const CurrentTimeLabel = ({}: Props) => {
8
- const { currentTime } = useSoftBuildersVideoPlayerContext();
9
-
10
- return <p>{durationFormater(currentTime)}</p>;
11
- };
12
-
13
- export default CurrentTimeLabel;
1
+ "use client";
2
+ import React, { useEffect } from "react";
3
+ import { durationFormater } from "../../utils";
4
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
5
+ type Props = {};
6
+
7
+ const CurrentTimeLabel = ({}: Props) => {
8
+ const { currentTime } = useSoftBuildersVideoPlayerContext();
9
+
10
+ return <p>{durationFormater(currentTime)}</p>;
11
+ };
12
+
13
+ export default CurrentTimeLabel;
@@ -1,18 +1,18 @@
1
- import React, { useEffect } from "react";
2
- import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
3
-
4
- const CurrentTimeTracker = () => {
5
- const { setCurrentTime, player } = useSoftBuildersVideoPlayerContext();
6
-
7
- useEffect(() => {
8
- const intervalId = setInterval(() => {
9
- setCurrentTime(player?.currentTime() || 0);
10
- }, 500);
11
-
12
- // Cleanup function to clear the interval
13
- return () => clearInterval(intervalId);
14
- }, [player]);
15
- return <></>;
16
- };
17
-
18
- export default CurrentTimeTracker;
1
+ import React, { useEffect } from "react";
2
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
3
+
4
+ const CurrentTimeTracker = () => {
5
+ const { setCurrentTime, player } = useSoftBuildersVideoPlayerContext();
6
+
7
+ useEffect(() => {
8
+ const intervalId = setInterval(() => {
9
+ setCurrentTime(player?.currentTime() || 0);
10
+ }, 500);
11
+
12
+ // Cleanup function to clear the interval
13
+ return () => clearInterval(intervalId);
14
+ }, [player]);
15
+ return <></>;
16
+ };
17
+
18
+ export default CurrentTimeTracker;
@@ -1,49 +1,49 @@
1
- import React from "react";
2
-
3
- type Props = {
4
- name: string;
5
- };
6
-
7
- const Menu = ({ name }: Props) => {
8
- return (
9
- <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">
10
- <div
11
- className="py-1"
12
- role="menu"
13
- aria-orientation="vertical"
14
- aria-labelledby={`${name}-button`}
15
- >
16
- <a
17
- href="#"
18
- className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900"
19
- role="menuitem"
20
- >
21
- Dashboard
22
- </a>
23
- <a
24
- href="#"
25
- className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900"
26
- role="menuitem"
27
- >
28
- Settings
29
- </a>
30
- <a
31
- href="#"
32
- className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900"
33
- role="menuitem"
34
- >
35
- Profile
36
- </a>
37
- <a
38
- href="#"
39
- className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900"
40
- role="menuitem"
41
- >
42
- Logout
43
- </a>
44
- </div>
45
- </div>
46
- );
47
- };
48
-
49
- export default Menu;
1
+ import React from "react";
2
+
3
+ type Props = {
4
+ name: string;
5
+ };
6
+
7
+ const Menu = ({ name }: Props) => {
8
+ return (
9
+ <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">
10
+ <div
11
+ className="py-1"
12
+ role="menu"
13
+ aria-orientation="vertical"
14
+ aria-labelledby={`${name}-button`}
15
+ >
16
+ <a
17
+ href="#"
18
+ className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900"
19
+ role="menuitem"
20
+ >
21
+ Dashboard
22
+ </a>
23
+ <a
24
+ href="#"
25
+ className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900"
26
+ role="menuitem"
27
+ >
28
+ Settings
29
+ </a>
30
+ <a
31
+ href="#"
32
+ className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900"
33
+ role="menuitem"
34
+ >
35
+ Profile
36
+ </a>
37
+ <a
38
+ href="#"
39
+ className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900"
40
+ role="menuitem"
41
+ >
42
+ Logout
43
+ </a>
44
+ </div>
45
+ </div>
46
+ );
47
+ };
48
+
49
+ export default Menu;
@@ -1,46 +1,46 @@
1
- import React, { useEffect, useState } from "react";
2
- import Tooltip from "../Tooltip";
3
- import { durationFormater } from "../../utils";
4
- import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
5
- import { SoftBuildersVideoPlayerNote } from "../../types";
6
- type Note = SoftBuildersVideoPlayerNote & { percentage: number };
7
-
8
- type Props = {
9
- note: Note;
10
- };
11
-
12
- const NoteTooltip = ({ note }: Props) => {
13
- const [open, setOpen] = useState(false);
14
- const { currentTime } = useSoftBuildersVideoPlayerContext();
15
-
16
- useEffect(() => {
17
- if (currentTime === Math.floor(note.time)) {
18
- setOpen(true);
19
-
20
- setTimeout(() => {
21
- setOpen(false);
22
- }, 5000);
23
- }
24
- }, [currentTime, note.time]);
25
- return (
26
- <div
27
- className="sb-w-1 sb-h-1 sb-rounded-full sb-bg-white sb-absolute sb-z-30"
28
- style={{ left: `${note.percentage}%` }}
29
- onMouseEnter={() => setOpen(true)}
30
- onMouseLeave={() => setOpen(false)}
31
- >
32
- <div className="sb-relative">
33
- <Tooltip open={open}>
34
- <div className="sb-flex sb-flex-col sb-gap-2 sb-items-center">
35
- <p>{note.label}</p>
36
- <p className="sb-p-2 sb-bg-[#303030] sb-bg-opacity-50 sb-rounded-md">
37
- {durationFormater(note.time)}
38
- </p>
39
- </div>
40
- </Tooltip>
41
- </div>
42
- </div>
43
- );
44
- };
45
-
46
- export default NoteTooltip;
1
+ import React, { useEffect, useState } from "react";
2
+ import Tooltip from "../Tooltip";
3
+ import { durationFormater } from "../../utils";
4
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
5
+ import { SoftBuildersVideoPlayerNote } from "../../types";
6
+ type Note = SoftBuildersVideoPlayerNote & { percentage: number };
7
+
8
+ type Props = {
9
+ note: Note;
10
+ };
11
+
12
+ const NoteTooltip = ({ note }: Props) => {
13
+ const [open, setOpen] = useState(false);
14
+ const { currentTime } = useSoftBuildersVideoPlayerContext();
15
+
16
+ useEffect(() => {
17
+ if (currentTime === Math.floor(note.time)) {
18
+ setOpen(true);
19
+
20
+ setTimeout(() => {
21
+ setOpen(false);
22
+ }, 5000);
23
+ }
24
+ }, [currentTime, note.time]);
25
+ return (
26
+ <div
27
+ className="sb-w-1 sb-h-1 sb-rounded-full sb-bg-white sb-absolute sb-z-30"
28
+ style={{ left: `${note.percentage}%` }}
29
+ onMouseEnter={() => setOpen(true)}
30
+ onMouseLeave={() => setOpen(false)}
31
+ >
32
+ <div className="sb-relative">
33
+ <Tooltip open={open}>
34
+ <div className="sb-flex sb-flex-col sb-gap-2 sb-items-center">
35
+ <p>{note.label}</p>
36
+ <p className="sb-p-2 sb-bg-[#303030] sb-bg-opacity-50 sb-rounded-md">
37
+ {durationFormater(note.time)}
38
+ </p>
39
+ </div>
40
+ </Tooltip>
41
+ </div>
42
+ </div>
43
+ );
44
+ };
45
+
46
+ export default NoteTooltip;
@@ -1,34 +1,34 @@
1
- import React, { useEffect, useState } from "react";
2
- import NoteTooltip from "../NoteTooltip";
3
- import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
4
- import { SoftBuildersVideoPlayerNote } from "../../types";
5
-
6
- type Note = SoftBuildersVideoPlayerNote & { percentage: number };
7
- type Props = {
8
- notes: SoftBuildersVideoPlayerNote[];
9
- };
10
- const NotesPanal = ({ notes }: Props) => {
11
- const [ns, setNs] = useState<Note[]>([]);
12
-
13
- const { duration } = useSoftBuildersVideoPlayerContext();
14
-
15
- useEffect(() => {
16
- const newNs = notes.map((n) => {
17
- const percentage = Math.floor((n.time * 100) / duration);
18
- return {
19
- ...n,
20
- percentage,
21
- };
22
- });
23
- setNs(newNs);
24
- }, [notes, duration]);
25
- return (
26
- <div id="notes-panal" className="sb-w-full sb-h-full sb-relative ">
27
- {ns.map((n, i) => (
28
- <NoteTooltip key={`note-${i}-${n.time}`} note={n} />
29
- ))}
30
- </div>
31
- );
32
- };
33
-
34
- export default NotesPanal;
1
+ import React, { useEffect, useState } from "react";
2
+ import NoteTooltip from "../NoteTooltip";
3
+ import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
4
+ import { SoftBuildersVideoPlayerNote } from "../../types";
5
+
6
+ type Note = SoftBuildersVideoPlayerNote & { percentage: number };
7
+ type Props = {
8
+ notes: SoftBuildersVideoPlayerNote[];
9
+ };
10
+ const NotesPanal = ({ notes }: Props) => {
11
+ const [ns, setNs] = useState<Note[]>([]);
12
+
13
+ const { duration } = useSoftBuildersVideoPlayerContext();
14
+
15
+ useEffect(() => {
16
+ const newNs = notes.map((n) => {
17
+ const percentage = Math.floor((n.time * 100) / duration);
18
+ return {
19
+ ...n,
20
+ percentage,
21
+ };
22
+ });
23
+ setNs(newNs);
24
+ }, [notes, duration]);
25
+ return (
26
+ <div id="notes-panal" className="sb-w-full sb-h-full sb-relative ">
27
+ {ns.map((n, i) => (
28
+ <NoteTooltip key={`note-${i}-${n.time}`} note={n} />
29
+ ))}
30
+ </div>
31
+ );
32
+ };
33
+
34
+ export default NotesPanal;
@@ -44,20 +44,20 @@ const TimeSlider = ({ chapters }) => {
44
44
  return (_jsxs("div", { className: " sb-w-full sb-h-2 sb-flex sb-items-center sb-justify-center", children: [_jsx("div", { className: "sb-absolute sb-top-0 sb-left-0 sb-w-full sb-z-10", children: _jsx(Slider, { value: timeSlider, handleValueChange: handleValueChange, min: MIN, max: MAX, style: {
45
45
  background: "transparent",
46
46
  } }) }), _jsx("div", { className: "sb-absolute sb-top-0 sb-left-0 sb-w-full sb-h-2 sb-bg-slate-400 sb-rounded-md", style: {
47
- background: `
48
- linear-gradient(to right,
49
- #f97316 0%,
50
- #f97316 ${timeSlider}%,
51
- #f9731640 ${timeSlider}%,
52
- #f9731640 ${downloadedBufferPercentage}%,
53
- #30303030 ${timeSlider}%,
54
- #30303030 100%
55
- )
47
+ background: `
48
+ linear-gradient(to right,
49
+ #f97316 0%,
50
+ #f97316 ${timeSlider}%,
51
+ #f9731640 ${timeSlider}%,
52
+ #f9731640 ${downloadedBufferPercentage}%,
53
+ #30303030 ${timeSlider}%,
54
+ #30303030 100%
55
+ )
56
56
  `,
57
- maskImage: `
58
- linear-gradient(to right,
59
- ${maskCuttes}
60
- )
57
+ maskImage: `
58
+ linear-gradient(to right,
59
+ ${maskCuttes}
60
+ )
61
61
  `,
62
62
  maskSize: "100% 100%",
63
63
  maskRepeat: "no-repeat",