l-min-components 1.0.387 → 1.0.392

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "l-min-components",
3
- "version": "1.0.387",
3
+ "version": "1.0.392",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src/assets",
@@ -35,9 +35,11 @@
35
35
  "react-input-emoji": "^5.3.1",
36
36
  "react-mic": "^12.4.6",
37
37
  "react-modal": "^3.16.1",
38
+ "react-player": "^2.13.0",
38
39
  "react-router-dom": "^6.8.2",
39
40
  "react-toastify": "^9.1.3",
40
41
  "react-tooltip": "^5.10.1",
42
+ "screenfull": "^6.0.2",
41
43
  "slate": "^0.94.0",
42
44
  "slate-history": "^0.93.0",
43
45
  "slate-react": "^0.94.0",
@@ -39,6 +39,7 @@ const AppMainLayout = () => {
39
39
  const [sideMenuLayout, setSideMenuLayout] = useState(true);
40
40
  const [defaultAcct, setDefaultAcct] = useState("");
41
41
  const [centerLayoutStyle, setCenterLayoutStyle] = useState({});
42
+ const [hideAffilicates, setHideAffilicates] = useState(false);
42
43
  const [affiliatesActive, setAffiliatesActive] = useState(false);
43
44
 
44
45
  useEffect(() => {
@@ -86,6 +87,7 @@ const AppMainLayout = () => {
86
87
  centerLayoutStyle,
87
88
  setCenterLayoutStyle,
88
89
  // return true if instructor affiliates is Active
90
+ setHideAffilicates,
89
91
  affiliatesActive,
90
92
  }}
91
93
  >
@@ -123,11 +125,14 @@ const AppMainLayout = () => {
123
125
  )}
124
126
  </LeftLayout>
125
127
  <CenterLayout isOpen={isOpen} style={centerLayoutStyle}>
126
- {window.location.pathname.includes("instructor") &&
127
- !window.location.pathname.includes("enterprise") &&
128
- !window.location.pathname.includes("manage-teams") && (
129
- <InstructorAccountSwitcher setAccountType={setAffiliatesActive} />
130
- )}
128
+ {window.location.pathname.includes("instructor") &&
129
+ !window.location.pathname.includes("enterprise") &&
130
+ !window.location.pathname.includes("manage-teams") &&
131
+ !hideAffilicates && (
132
+ <InstructorAccountSwitcher
133
+ setAccountType={setAffiliatesActive}
134
+ />
135
+ )}
131
136
 
132
137
  <Outlet />
133
138
  </CenterLayout>
@@ -33,4 +33,5 @@ export { default as TextEditor } from "./textEditor";
33
33
  export { default as MessageAddon } from "./messageAddon/messages";
34
34
  export { default as InstructorAccountSwitcher } from "./instructorAccountSwitcher";
35
35
  export { default as InstructorRightBar } from "./fileRightBar/instructorRightBar";
36
- export { default as EnterpriseRightBar } from "./fileRightBar/enterpriseRightBar";
36
+ export { default as VideoPlayer } from "./videoPlayer";
37
+ export { default as EnterpriseRightBar } from "./fileRightBar/enterpriseRightBar";
@@ -75,7 +75,7 @@ const InstructorAccountSwitcher = ({ setAccountType }) => {
75
75
  </ExpiryModalContent>
76
76
  </ExpiryModal>
77
77
  )}
78
- <Container>
78
+ <Container className="instructor_account_switcher">
79
79
  <div className="left">
80
80
  {switchValue !== "affiliates" && (
81
81
  <p onClick={() => setExpiryFlow("expiry")}>Frank Language Expert</p>
@@ -0,0 +1,23 @@
1
+ const PauseIcon = ({ fill, onClick }) => {
2
+ return (
3
+ <svg
4
+ onClick={onClick}
5
+ width="800px"
6
+ height="800px"
7
+ viewBox="0 0 24 24"
8
+ fill="none"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ >
11
+ <path
12
+ d="M2 6C2 4.11438 2 3.17157 2.58579 2.58579C3.17157 2 4.11438 2 6 2C7.88562 2 8.82843 2 9.41421 2.58579C10 3.17157 10 4.11438 10 6V18C10 19.8856 10 20.8284 9.41421 21.4142C8.82843 22 7.88562 22 6 22C4.11438 22 3.17157 22 2.58579 21.4142C2 20.8284 2 19.8856 2 18V6Z"
13
+ fill={fill || "#1C274C"}
14
+ />
15
+ <path
16
+ d="M14 6C14 4.11438 14 3.17157 14.5858 2.58579C15.1716 2 16.1144 2 18 2C19.8856 2 20.8284 2 21.4142 2.58579C22 3.17157 22 4.11438 22 6V18C22 19.8856 22 20.8284 21.4142 21.4142C20.8284 22 19.8856 22 18 22C16.1144 22 15.1716 22 14.5858 21.4142C14 20.8284 14 19.8856 14 18V6Z"
17
+ fill={fill || "#1C274C"}
18
+ />
19
+ </svg>
20
+ );
21
+ };
22
+
23
+ export default PauseIcon;
@@ -0,0 +1,18 @@
1
+ const PlayVideoIcon = () => {
2
+ return (
3
+ <svg
4
+ width="23"
5
+ height="23"
6
+ viewBox="0 0 23 23"
7
+ fill="none"
8
+ xmlns="http://www.w3.org/2000/svg"
9
+ >
10
+ <path
11
+ d="M0.632812 11.2832V6.72359C0.632812 1.06246 4.86949 -1.25578 10.0537 1.57478L14.2362 3.8546L18.4187 6.13442C23.6029 8.96499 23.6029 13.6015 18.4187 16.432L14.2362 18.7119L10.0537 20.9917C4.86949 23.8223 0.632812 21.504 0.632812 15.8429V11.2832Z"
12
+ fill="white"
13
+ />
14
+ </svg>
15
+ );
16
+ };
17
+
18
+ export default PlayVideoIcon;
@@ -0,0 +1,47 @@
1
+ const VideoScreenIcon = ({ onClick }) => {
2
+ return (
3
+ <svg
4
+ onClick={onClick}
5
+ width="17"
6
+ height="16"
7
+ viewBox="0 0 17 16"
8
+ fill="none"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ >
11
+ <path
12
+ d="M10.4297 1.82031H11.7593C13.7538 1.82031 15.0834 3.07845 15.0834 4.96567V6.22381"
13
+ stroke="#7C8080"
14
+ strokeWidth="1.5"
15
+ strokeMiterlimit="10"
16
+ strokeLinecap="round"
17
+ strokeLinejoin="round"
18
+ />
19
+ <path
20
+ d="M1.78711 6.22381V4.96567C1.78711 3.07845 3.11674 1.82031 5.11117 1.82031H6.4408"
21
+ stroke="#7C8080"
22
+ strokeWidth="1.5"
23
+ strokeMiterlimit="10"
24
+ strokeLinecap="round"
25
+ strokeLinejoin="round"
26
+ />
27
+ <path
28
+ d="M10.4297 14.4035H11.7593C13.7538 14.4035 15.0834 13.1454 15.0834 11.2581V10"
29
+ stroke="#7C8080"
30
+ strokeWidth="1.5"
31
+ strokeMiterlimit="10"
32
+ strokeLinecap="round"
33
+ strokeLinejoin="round"
34
+ />
35
+ <path
36
+ d="M1.78711 10V11.2581C1.78711 13.1454 3.11674 14.4035 5.11117 14.4035H6.4408"
37
+ stroke="#7C8080"
38
+ strokeWidth="1.5"
39
+ strokeMiterlimit="10"
40
+ strokeLinecap="round"
41
+ strokeLinejoin="round"
42
+ />
43
+ </svg>
44
+ );
45
+ };
46
+
47
+ export default VideoScreenIcon;
@@ -0,0 +1,170 @@
1
+ import { useState, useRef, useEffect } from "react";
2
+ import screenfull from "screenfull";
3
+ import {
4
+ RangeContainer,
5
+ VideoController,
6
+ VideoPlayerContainer,
7
+ VideoPrompts,
8
+ } from "./index.styled";
9
+ import ReactPlayer from "react-player";
10
+ import VideoScreenIcon from "./icons/videoScreenIcon";
11
+ import PlayIcon from "./icons/playVideoIcon";
12
+ import PauseIcon from "./icons/pause";
13
+
14
+ const VideoPlayer = ({
15
+ width,
16
+ height,
17
+ style,
18
+ src,
19
+ hideRange,
20
+ showPrompts,
21
+ controlSize,
22
+ }) => {
23
+ const [player, setPlayer] = useState({
24
+ playing: false,
25
+ played: 0,
26
+ seeking: false,
27
+ });
28
+ const [hideController, setHideController] = useState(false);
29
+ const [count, setCount] = useState(0);
30
+ const playContainerRef = useRef();
31
+ const playerRef = useRef();
32
+ const { playing, played, seeking } = player;
33
+
34
+ const format = (secs) => {
35
+ const sec_num = parseInt(secs, 10);
36
+ const hours = Math.floor(sec_num / 3600);
37
+ const minutes = Math.floor(sec_num / 60) % 60;
38
+ const seconds = sec_num % 60;
39
+
40
+ return [hours, minutes, seconds]
41
+ .map((v) => (v < 10 ? "0" + v : v))
42
+ .join(":");
43
+ };
44
+
45
+ const handlePlayPause = () => {
46
+ setPlayer({ ...player, playing: !player.playing });
47
+ };
48
+
49
+ const handleFullScreen = () => {
50
+ screenfull.toggle(playContainerRef.current);
51
+ };
52
+
53
+ const handleProgess = (changeState) => {
54
+ if (count > 3) {
55
+ setHideController(true);
56
+ setCount(0);
57
+ }
58
+ if (!hideController) {
59
+ setCount(count + 1);
60
+ }
61
+ if (seeking === false) {
62
+ setPlayer({ ...player, ...changeState });
63
+ }
64
+ };
65
+
66
+ const handleSeek = (e) => {
67
+ setPlayer({ ...player, played: parseFloat(e.target?.value / 100) });
68
+ };
69
+ const handleSeekMouseDown = () => {
70
+ setPlayer({ ...player, seeking: true });
71
+ };
72
+ const handleSeekMouseUp = (e) => {
73
+ setPlayer({ ...player, seeking: false });
74
+ playerRef.current?.seekTo(e.target?.value / 100);
75
+ };
76
+
77
+ const handleMouseMove = () => {
78
+ setHideController(false);
79
+ setCount(0);
80
+ };
81
+
82
+ const calcShowPrompts = () => {
83
+ if (player?.playedSeconds) {
84
+ return Math.floor((player.playedSeconds * 100) / player.loadedSeconds);
85
+ }
86
+ };
87
+ const currentValue = playerRef?.current?.getCurrentTime();
88
+ const durrationValue = playerRef.current?.getDuration();
89
+ useEffect(() => {
90
+ if (currentValue && durrationValue) {
91
+ if (currentValue === durrationValue) {
92
+ setTimeout(() => {
93
+ setPlayer({ ...player, playing: false });
94
+ setHideController(false);
95
+ setCount(0);
96
+ }, 500);
97
+ }
98
+ }
99
+ }, [currentValue, durrationValue, player]);
100
+
101
+ const currentTime = playerRef.current
102
+ ? format(playerRef.current?.getCurrentTime())
103
+ : "00:00:00";
104
+
105
+ const duration = playerRef.current
106
+ ? format(playerRef.current?.getDuration())
107
+ : "00:00:00";
108
+
109
+ return (
110
+ <VideoPlayerContainer
111
+ ref={playContainerRef}
112
+ style={style}
113
+ width={width}
114
+ height={height}
115
+ onMouseMove={handleMouseMove}
116
+ >
117
+ {showPrompts && calcShowPrompts() > 80 && (
118
+ <VideoPrompts>
119
+ <div>
120
+ <p>Continue watching</p>
121
+ <p>Previuos Part (Lesson 1)</p>
122
+ </div>
123
+ <div>
124
+ <p>Continue watching</p>
125
+ <p>Next Part (Lesson 6)</p>
126
+ </div>
127
+ </VideoPrompts>
128
+ )}
129
+ <ReactPlayer
130
+ width="100%"
131
+ ref={playerRef}
132
+ height="100%"
133
+ url={
134
+ src ||
135
+ "https://joy1.videvo.net/videvo_files/video/free/video0474/small_watermarked/_import_61ea3dd6ab62a0.19123787_preview.mp4"
136
+ }
137
+ // muted={true}
138
+ playing={playing}
139
+ onProgress={handleProgess}
140
+ />
141
+ <VideoController hide={hideController} size={controlSize}>
142
+ {!hideRange && (
143
+ <RangeContainer>
144
+ <p>
145
+ {currentTime} / {duration}
146
+ </p>
147
+ <input
148
+ type="range"
149
+ name=""
150
+ id=""
151
+ className="range"
152
+ min={0}
153
+ max={100}
154
+ onChange={handleSeek}
155
+ onMouseDown={handleSeekMouseDown}
156
+ onMouseUp={handleSeekMouseUp}
157
+ value={played * 100}
158
+ />
159
+ <VideoScreenIcon onClick={handleFullScreen} />
160
+ </RangeContainer>
161
+ )}
162
+ <div className="play_pause_wrap" onClick={handlePlayPause}>
163
+ {playing ? <PauseIcon fill="#fff" /> : <PlayIcon fill="#fff" />}
164
+ </div>
165
+ </VideoController>
166
+ </VideoPlayerContainer>
167
+ );
168
+ };
169
+
170
+ export default VideoPlayer;
@@ -0,0 +1,149 @@
1
+ import styled from "styled-components";
2
+
3
+ export const VideoPlayerContainer = styled.div`
4
+ position: relative;
5
+ border-radius: 24px;
6
+ overflow: hidden;
7
+ /* background: #f5f7f7; */
8
+ width: ${({ width }) => (width ? width : "auto")};
9
+ height: ${({ height }) => (height ? height : "auto")};
10
+ video {
11
+ object-fit: contain;
12
+ }
13
+ `;
14
+
15
+ export const VideoController = styled.div`
16
+ position: absolute;
17
+ padding: 22px 26px;
18
+ z-index: 2;
19
+ inset: 0;
20
+ display: flex;
21
+ align-items: flex-end;
22
+ visibility: ${({ hide }) => (hide ? "hidden" : "visible")};
23
+ .play_pause_wrap {
24
+ position: absolute;
25
+ left: 50%;
26
+ top: 50%;
27
+ transform: translate(-50%, -50%);
28
+ width: 64px;
29
+ height: 64px;
30
+ display: flex;
31
+ align-items: center;
32
+ justify-content: center;
33
+ background: rgba(0, 0, 0, 0.2);
34
+ border-radius: 50%;
35
+ cursor: pointer;
36
+
37
+ svg {
38
+ width: 30px;
39
+ height: 30px;
40
+ }
41
+ }
42
+ `;
43
+
44
+ export const RangeContainer = styled.div`
45
+ border-radius: 16.5px;
46
+ width: 100%;
47
+ height: 29.307px;
48
+ background: #fff;
49
+ display: flex;
50
+ align-items: center;
51
+ padding: 6.5px 12.5px;
52
+ gap: 15px;
53
+ position: relative;
54
+ p {
55
+ position: absolute;
56
+ color: #b0dcdc;
57
+ font-size: 10px;
58
+ left: 40px;
59
+ }
60
+ svg {
61
+ cursor: pointer;
62
+ }
63
+ .range {
64
+ border-radius: 9px;
65
+ flex: 1;
66
+ -webkit-appearance: none;
67
+ appearance: none;
68
+ overflow: hidden;
69
+ &::-webkit-slider-runnable-track {
70
+ height: 15px;
71
+ background: rgba(198, 204, 204, 0.4);
72
+ border-radius: 16px;
73
+ }
74
+
75
+ &::-moz-range-track {
76
+ height: 15px;
77
+ background: rgba(198, 204, 204, 0.4);
78
+ border-radius: 16px;
79
+ }
80
+
81
+ &::-webkit-slider-thumb {
82
+ -webkit-appearance: none;
83
+ appearance: none;
84
+ height: 15px;
85
+ width: 15px;
86
+ background-color: #099;
87
+ border-radius: 50%;
88
+ border: 2px solid #099;
89
+ box-shadow: -9999px 0 0 9993px #099;
90
+ }
91
+
92
+ &::-moz-range-thumb {
93
+ height: 15px;
94
+ width: 15px;
95
+ background-color: #099;
96
+ border-radius: 50%;
97
+ border: 1px solid #099;
98
+ box-shadow: -9999px 0 0 9993px #099;
99
+ }
100
+ }
101
+ /* .range::-webkit-slider-thumb {
102
+ box-shadow: 0 0 9999px ;
103
+ border-radius: 9999px;
104
+ } */
105
+ `;
106
+
107
+ export const VideoPrompts = styled.div`
108
+ position: absolute;
109
+ left: 0;
110
+ right: 0;
111
+ top: 20px;
112
+ z-index: 30;
113
+ display: flex;
114
+ justify-content: space-between;
115
+ align-items: center;
116
+ div {
117
+ cursor: pointer;
118
+ border-radius: 0px 8px 8px 0px;
119
+ background: #fff;
120
+ height: 48px;
121
+ min-width: 220px;
122
+ padding: 2px 18px;
123
+ border-radius: 0px 8px 8px 0px;
124
+ width: fit-content;
125
+ &:nth-child(2) {
126
+ border-radius: 8px 0px 0px 8px;
127
+ }
128
+ p {
129
+ font-size: 16px;
130
+ font-weight: 700;
131
+ line-height: 22px;
132
+ &:nth-child(1) {
133
+ color: #00c2c2;
134
+ &::before {
135
+ content: "";
136
+ display: inline-block;
137
+ border-radius: 50%;
138
+ width: 12px;
139
+ height: 12px;
140
+ background-color: #00c2c2;
141
+ margin-right: 7px;
142
+ }
143
+ }
144
+ &:nth-child(2) {
145
+ color: #febf10;
146
+ }
147
+ }
148
+ }
149
+ `;