softbuilders-react-video-player 1.1.7 → 1.1.9
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +21 -21
- package/README.md +126 -126
- package/dist/components/BigPlayButton/index.tsx +31 -31
- package/dist/components/BufferTracker/index.tsx +19 -19
- package/dist/components/ChapterTooltip/index.tsx +65 -65
- package/dist/components/ChaptersPanal/index.tsx +40 -40
- package/dist/components/ControlBar/index.d.ts +2 -1
- package/dist/components/ControlBar/index.js +19 -5
- package/dist/components/ControlBar/index.js.map +1 -1
- package/dist/components/ControlBar/index.tsx +149 -127
- package/dist/components/CreateNoteMenu/index.tsx +61 -61
- package/dist/components/CurrentTimeLabel/index.tsx +13 -13
- package/dist/components/CurrentTimeTracker/index.tsx +18 -18
- package/dist/components/Menu/index.tsx +49 -49
- package/dist/components/MenuButton/index.js +1 -1
- package/dist/components/MenuButton/index.js.map +1 -1
- package/dist/components/MenuButton/index.tsx +67 -67
- package/dist/components/NoteTooltip/index.tsx +46 -46
- package/dist/components/NotesPanal/index.tsx +34 -34
- package/dist/components/QualityMenu/index.js +2 -2
- package/dist/components/QualityMenu/index.js.map +1 -1
- package/dist/components/QualityMenu/index.tsx +122 -122
- package/dist/components/Slider/index.d.ts +1 -1
- package/dist/components/Slider/index.js +3 -3
- package/dist/components/Slider/index.js.map +1 -1
- package/dist/components/Slider/index.tsx +36 -37
- package/dist/components/Slider/style.css +49 -15
- package/dist/components/SoftBuildersVideoPlayer/index.js +1 -1
- package/dist/components/SoftBuildersVideoPlayer/index.js.map +1 -1
- package/dist/components/SoftBuildersVideoPlayer/index.tsx +110 -109
- package/dist/components/SubtitleMenu/index.js +2 -2
- package/dist/components/SubtitleMenu/index.js.map +1 -1
- package/dist/components/SubtitleMenu/index.tsx +107 -108
- package/dist/components/TimeSlider/index.js +13 -13
- package/dist/components/TimeSlider/index.tsx +107 -107
- package/dist/components/TimeSliderContainer/index.tsx +35 -35
- package/dist/components/Tooltip/index.tsx +16 -16
- package/dist/components/VideoPlayerComponent/index.d.ts +2 -1
- package/dist/components/VideoPlayerComponent/index.js +37 -34
- package/dist/components/VideoPlayerComponent/index.js.map +1 -1
- package/dist/components/VideoPlayerComponent/index.tsx +260 -249
- package/dist/components/VideoPlayerComponent/provider.tsx +82 -82
- package/dist/components/VideoPlayerComponent/style/style.css +36 -36
- package/dist/components/VolumeSlider/index.d.ts +4 -2
- package/dist/components/VolumeSlider/index.js +12 -2
- package/dist/components/VolumeSlider/index.js.map +1 -1
- package/dist/components/VolumeSlider/index.tsx +91 -52
- package/dist/components/icons/SubIcon.d.ts +3 -0
- package/dist/components/icons/SubIcon.js +4 -0
- package/dist/components/icons/SubIcon.js.map +1 -0
- package/dist/components/icons/SubIcon.tsx +28 -0
- package/dist/components/icons/index.d.ts +1 -0
- package/dist/components/icons/index.js +1 -0
- package/dist/components/icons/index.js.map +1 -1
- package/dist/components/icons/index.ts +15 -14
- package/dist/images/index.d.ts +1 -0
- package/dist/images/index.js +1 -0
- package/dist/images/index.js.map +1 -1
- package/dist/index.css +75 -3
- package/dist/index.mjs +253 -166
- package/dist/styles/tailwind.css +137 -87
- package/package.json +45 -45
@@ -1,5 +1,5 @@
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
-
import { useEffect } from "react";
|
2
|
+
import { useEffect, useState } from "react";
|
3
3
|
import CurrentTimeLabel from "../CurrentTimeLabel";
|
4
4
|
import { durationFormater } from "../../utils";
|
5
5
|
import VolumeSlider from "../VolumeSlider";
|
@@ -10,13 +10,27 @@ import BufferTracker from "../BufferTracker";
|
|
10
10
|
import CurrentTimeTracker from "../CurrentTimeTracker";
|
11
11
|
import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
|
12
12
|
import SubtitleMenu from "../SubtitleMenu";
|
13
|
-
import { BackwardIcon, ForwardIcon, FullScreenIcon, PauseIcon, PlayIcon } from "../../images";
|
14
|
-
const ControlBar = ({ player, isPaused, setIsPaused, duration, notes, chapters, seekStep = 5, handleSaveNoteAction, }) => {
|
13
|
+
import { BackwardIcon, ForwardIcon, FullScreenIcon, PauseIcon, PlayIcon, } from "../../images";
|
14
|
+
const ControlBar = ({ player, isPaused, setIsPaused, duration, notes, chapters, seekStep = 5, id, handleSaveNoteAction, }) => {
|
15
15
|
const { setPlayer, setDuration } = useSoftBuildersVideoPlayerContext();
|
16
|
+
const [width, setwidth] = useState(null);
|
16
17
|
const seek = (duration) => {
|
17
18
|
const currentTime = Number((player === null || player === void 0 ? void 0 : player.currentTime()) || 0);
|
18
19
|
player === null || player === void 0 ? void 0 : player.currentTime(currentTime + duration);
|
19
20
|
};
|
21
|
+
const container = document.getElementById(`video-container-${id}`);
|
22
|
+
function handleWidthChange(width) {
|
23
|
+
setwidth(width);
|
24
|
+
console.log(width);
|
25
|
+
}
|
26
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
27
|
+
for (let entry of entries) {
|
28
|
+
const currentWidth = entry.contentRect.width;
|
29
|
+
handleWidthChange(currentWidth); // Call the action when width changes
|
30
|
+
}
|
31
|
+
});
|
32
|
+
// Start observing the element
|
33
|
+
resizeObserver.observe(container);
|
20
34
|
const togglePlay = () => {
|
21
35
|
if (isPaused)
|
22
36
|
player === null || player === void 0 ? void 0 : player.play();
|
@@ -30,11 +44,11 @@ const ControlBar = ({ player, isPaused, setIsPaused, duration, notes, chapters,
|
|
30
44
|
useEffect(() => {
|
31
45
|
setDuration(duration);
|
32
46
|
}, [duration]);
|
33
|
-
return (_jsxs("div", { className: "
|
47
|
+
return (_jsxs("div", { className: " sb-px-2 sb-flex sb-justify-center sb-gap-3 sb-w-full sb-h-full sb-items-end pb-2", children: [_jsx(BufferTracker, {}), _jsx(CurrentTimeTracker, {}), _jsx("button", { onClick: () => {
|
34
48
|
seek(-seekStep);
|
35
49
|
}, children: _jsx(BackwardIcon, { className: "sb-w-3 sb-h-3" }) }), _jsx("button", { onClick: togglePlay, children: isPaused ? (_jsx(PlayIcon, { className: "sb-w-3 sb-h-3" })) : (_jsx(PauseIcon, { className: "sb-w-3 sb-h-3" })) }), _jsx("button", { onClick: () => {
|
36
50
|
seek(seekStep);
|
37
|
-
}, children: _jsx(ForwardIcon, { className: "sb-w-3 sb-h-3" }) }), _jsx(CurrentTimeLabel, {}), _jsx("div", { className: "sb-w-[30%] hover:sb-w-[45%] sb-transition-all sb-ease-in-out sb-duration-500", children: _jsx(TimeSliderContainer, { chapters: chapters, notes: notes }) }), _jsx("p", { children: durationFormater(duration) }), _jsx("div", { className: "sb-
|
51
|
+
}, children: _jsx(ForwardIcon, { className: "sb-w-3 sb-h-3" }) }), _jsx(CurrentTimeLabel, {}), _jsx("div", { className: "sb-w-[30%] hover:sb-w-[45%] sb-transition-all sb-ease-in-out sb-duration-500", children: _jsx(TimeSliderContainer, { chapters: chapters, notes: notes }) }), _jsx("p", { children: durationFormater(duration) }), _jsx("div", { className: "sb-h-full", children: _jsx(VolumeSlider, { width: width }) }), _jsx(QualityMenu, {}), _jsx("button", { onClick: () => {
|
38
52
|
if (player === null || player === void 0 ? void 0 : player.isFullscreen()) {
|
39
53
|
player === null || player === void 0 ? void 0 : player.exitFullscreen();
|
40
54
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ControlBar/index.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/ControlBar/index.tsx"],"names":[],"mappings":"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"}
|
@@ -1,127 +1,149 @@
|
|
1
|
-
import React, { useEffect } from "react";
|
2
|
-
|
3
|
-
import Player from "video.js/dist/types/player";
|
4
|
-
import CurrentTimeLabel from "../CurrentTimeLabel";
|
5
|
-
import { durationFormater } from "../../utils";
|
6
|
-
import VolumeSlider from "../VolumeSlider";
|
7
|
-
import QualityMenu from "../QualityMenu";
|
8
|
-
|
9
|
-
import CreateNoteMenu from "../CreateNoteMenu";
|
10
|
-
import TimeSliderContainer from "../TimeSliderContainer";
|
11
|
-
import BufferTracker from "../BufferTracker";
|
12
|
-
import CurrentTimeTracker from "../CurrentTimeTracker";
|
13
|
-
import {
|
14
|
-
SoftBuildersVideoPlayerChapter,
|
15
|
-
SoftBuildersVideoPlayerNote,
|
16
|
-
} from "../../types";
|
17
|
-
import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
|
18
|
-
import SubtitleMenu from "../SubtitleMenu";
|
19
|
-
import {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
<
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
<button
|
107
|
-
onClick={() => {
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
)}
|
121
|
-
|
122
|
-
<
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
1
|
+
import React, { useEffect, useState } from "react";
|
2
|
+
|
3
|
+
import Player from "video.js/dist/types/player";
|
4
|
+
import CurrentTimeLabel from "../CurrentTimeLabel";
|
5
|
+
import { durationFormater } from "../../utils";
|
6
|
+
import VolumeSlider from "../VolumeSlider";
|
7
|
+
import QualityMenu from "../QualityMenu";
|
8
|
+
|
9
|
+
import CreateNoteMenu from "../CreateNoteMenu";
|
10
|
+
import TimeSliderContainer from "../TimeSliderContainer";
|
11
|
+
import BufferTracker from "../BufferTracker";
|
12
|
+
import CurrentTimeTracker from "../CurrentTimeTracker";
|
13
|
+
import {
|
14
|
+
SoftBuildersVideoPlayerChapter,
|
15
|
+
SoftBuildersVideoPlayerNote,
|
16
|
+
} from "../../types";
|
17
|
+
import { useSoftBuildersVideoPlayerContext } from "../VideoPlayerComponent/provider";
|
18
|
+
import SubtitleMenu from "../SubtitleMenu";
|
19
|
+
import {
|
20
|
+
BackwardIcon,
|
21
|
+
ForwardIcon,
|
22
|
+
FullScreenIcon,
|
23
|
+
PauseIcon,
|
24
|
+
PlayIcon,
|
25
|
+
} from "../../images";
|
26
|
+
|
27
|
+
type Props<T> = {
|
28
|
+
player: Player | undefined;
|
29
|
+
isPaused: boolean;
|
30
|
+
setIsPaused: React.Dispatch<React.SetStateAction<boolean>>;
|
31
|
+
duration: number;
|
32
|
+
notes: SoftBuildersVideoPlayerNote[];
|
33
|
+
chapters: SoftBuildersVideoPlayerChapter[];
|
34
|
+
seekStep?: number;
|
35
|
+
id?: string;
|
36
|
+
handleSaveNoteAction?: (time: number, note: string) => Promise<T>;
|
37
|
+
};
|
38
|
+
const ControlBar = <T,>({
|
39
|
+
player,
|
40
|
+
isPaused,
|
41
|
+
setIsPaused,
|
42
|
+
duration,
|
43
|
+
notes,
|
44
|
+
chapters,
|
45
|
+
seekStep = 5,
|
46
|
+
id,
|
47
|
+
handleSaveNoteAction,
|
48
|
+
}: Props<T>) => {
|
49
|
+
const { setPlayer, setDuration } = useSoftBuildersVideoPlayerContext();
|
50
|
+
const [width, setwidth] = useState(null);
|
51
|
+
|
52
|
+
const seek = (duration: number) => {
|
53
|
+
const currentTime = Number(player?.currentTime() || 0);
|
54
|
+
player?.currentTime(currentTime + duration);
|
55
|
+
};
|
56
|
+
const container = document.getElementById(`video-container-${id}`);
|
57
|
+
function handleWidthChange(width) {
|
58
|
+
setwidth(width);
|
59
|
+
console.log(width);
|
60
|
+
}
|
61
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
62
|
+
for (let entry of entries) {
|
63
|
+
const currentWidth = entry.contentRect.width;
|
64
|
+
handleWidthChange(currentWidth); // Call the action when width changes
|
65
|
+
}
|
66
|
+
});
|
67
|
+
|
68
|
+
// Start observing the element
|
69
|
+
resizeObserver.observe(container);
|
70
|
+
const togglePlay = () => {
|
71
|
+
if (isPaused) player?.play();
|
72
|
+
else player?.pause();
|
73
|
+
|
74
|
+
setIsPaused(!isPaused);
|
75
|
+
};
|
76
|
+
|
77
|
+
useEffect(() => {
|
78
|
+
setPlayer(player);
|
79
|
+
}, [player]);
|
80
|
+
|
81
|
+
useEffect(() => {
|
82
|
+
setDuration(duration);
|
83
|
+
}, [duration]);
|
84
|
+
|
85
|
+
return (
|
86
|
+
<div className=" sb-px-2 sb-flex sb-justify-center sb-gap-3 sb-w-full sb-h-full sb-items-end pb-2">
|
87
|
+
{/* Doesn't display anything, just set the downloaded buffer persentage */}
|
88
|
+
<BufferTracker />
|
89
|
+
{/* Doesn't display anything, just set the current time */}
|
90
|
+
<CurrentTimeTracker />
|
91
|
+
|
92
|
+
<button
|
93
|
+
onClick={() => {
|
94
|
+
seek(-seekStep);
|
95
|
+
}}
|
96
|
+
>
|
97
|
+
<BackwardIcon className="sb-w-3 sb-h-3" />
|
98
|
+
</button>
|
99
|
+
<button onClick={togglePlay}>
|
100
|
+
{isPaused ? (
|
101
|
+
<PlayIcon className="sb-w-3 sb-h-3" />
|
102
|
+
) : (
|
103
|
+
<PauseIcon className="sb-w-3 sb-h-3" />
|
104
|
+
)}
|
105
|
+
</button>
|
106
|
+
<button
|
107
|
+
onClick={() => {
|
108
|
+
seek(seekStep);
|
109
|
+
}}
|
110
|
+
>
|
111
|
+
<ForwardIcon className="sb-w-3 sb-h-3" />
|
112
|
+
</button>
|
113
|
+
|
114
|
+
<CurrentTimeLabel />
|
115
|
+
|
116
|
+
<div className="sb-w-[30%] hover:sb-w-[45%] sb-transition-all sb-ease-in-out sb-duration-500">
|
117
|
+
<TimeSliderContainer chapters={chapters} notes={notes} />
|
118
|
+
</div>
|
119
|
+
|
120
|
+
<p>{durationFormater(duration)}</p>
|
121
|
+
|
122
|
+
<div className="sb-h-full">
|
123
|
+
<VolumeSlider width={width} />
|
124
|
+
</div>
|
125
|
+
|
126
|
+
<QualityMenu />
|
127
|
+
|
128
|
+
<button
|
129
|
+
onClick={() => {
|
130
|
+
if (player?.isFullscreen()) {
|
131
|
+
player?.exitFullscreen();
|
132
|
+
} else {
|
133
|
+
player?.requestFullscreen();
|
134
|
+
}
|
135
|
+
}}
|
136
|
+
>
|
137
|
+
<FullScreenIcon className="sb-w-3 sb-h-3" />
|
138
|
+
</button>
|
139
|
+
|
140
|
+
{handleSaveNoteAction && (
|
141
|
+
<CreateNoteMenu handleSaveNoteAction={handleSaveNoteAction} />
|
142
|
+
)}
|
143
|
+
|
144
|
+
<SubtitleMenu />
|
145
|
+
</div>
|
146
|
+
);
|
147
|
+
};
|
148
|
+
|
149
|
+
export default ControlBar;
|
@@ -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;
|
@@ -24,7 +24,7 @@ const MenuButton = ({ buttonContent, menuContent, close }) => {
|
|
24
24
|
if (close)
|
25
25
|
close(closeMenu);
|
26
26
|
}, [close, closeMenu]);
|
27
|
-
return (_jsxs("div", { className: "sb-relative", children: [_jsx("button", { ref: buttonRef, onClick: toggleMenu, "aria-haspopup": "true", "aria-expanded": isOpen, "aria-label": "Open menu", children: buttonContent }), isOpen && (_jsx("div", { ref: menuRef, role: "menu", "aria-orientation": "vertical", "aria-labelledby": "Open menu", className: "sb-absolute sb-shadow-lg sb-right-0 sb-bottom-10", children: menuContent }))] }));
|
27
|
+
return (_jsxs("div", { className: "sb-relative sb-flex sb-items-end", children: [_jsx("button", { ref: buttonRef, onClick: toggleMenu, "aria-haspopup": "true", "aria-expanded": isOpen, "aria-label": "Open menu", children: buttonContent }), isOpen && (_jsx("div", { ref: menuRef, role: "menu", "aria-orientation": "vertical", "aria-labelledby": "Open menu", className: "sb-absolute sb-shadow-lg sb-right-0 sb-bottom-10", children: menuContent }))] }));
|
28
28
|
};
|
29
29
|
export default MenuButton;
|
30
30
|
//# sourceMappingURL=index.js.map
|