|
1 | 1 | import React, { useState, useEffect } from 'react'; |
2 | 2 | import { useSelector, useDispatch } from 'react-redux'; |
3 | 3 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |
| 4 | +import ReactPlayer from 'react-player'; |
4 | 5 |
|
5 | | -import { dispatchAction } from 'store/actions'; |
| 6 | +import Slider from '@mui/material/Slider'; |
6 | 7 |
|
| 8 | +import { dispatchAction } from 'store/actions'; |
7 | 9 | import * as FaIcons from '@fortawesome/free-solid-svg-icons'; |
8 | 10 | import * as FaRegIcons from '@fortawesome/free-regular-svg-icons'; |
9 | 11 | import * as MUIcons from '@mui/icons-material'; |
10 | 12 | import * as AllIcons from 'components/icons'; |
11 | 13 |
|
| 14 | +const {round, floor, random, min, max, abs} = Math; |
| 15 | + |
12 | 16 | export const MaterialIcon = (props) => { |
13 | 17 | var icon = props.mui; |
14 | 18 | if (props.out) icon += "Outlined"; |
@@ -113,7 +117,9 @@ export const Image = (props) => { |
113 | 117 | src += ".png"; |
114 | 118 | } |
115 | 119 |
|
116 | | - if(props.ext) src = props.src |
| 120 | + if (props.ext || (props.src && props.src.includes("http"))) { |
| 121 | + src = props.src; |
| 122 | + } |
117 | 123 |
|
118 | 124 | const errorHandler = (e)=>{ |
119 | 125 | if(props.err) e.target.src = props.err |
@@ -142,6 +148,77 @@ export const Image = (props) => { |
142 | 148 | ) |
143 | 149 | } |
144 | 150 |
|
| 151 | +const formatseconds = (sec)=>{ |
| 152 | + if (!sec) return "00:00"; |
| 153 | + var res = floor(sec / 60); |
| 154 | + res += ':'; |
| 155 | + sec %= 60; |
| 156 | + if (sec < 10) res += "0"; |
| 157 | + res += sec; |
| 158 | + |
| 159 | + return res; |
| 160 | +} |
| 161 | + |
| 162 | +export const Video = (props) => { |
| 163 | + const dispatch = useDispatch(); |
| 164 | + const [play, setPlay] = useState(props.autoplay); |
| 165 | + const [prog, setProg] = useState(0); // time elapsed |
| 166 | + const [perProg, setPerProg] = useState(0); // time elapsed in % |
| 167 | + |
| 168 | + var src = `/img/${(props.dir?props.dir+"/":"")+props.src}`; |
| 169 | + if (props.src && !props.src.includes(".")) src += ".mp4"; |
| 170 | + |
| 171 | + if (props.ext || (props.src && props.src.includes("http"))) { |
| 172 | + src = props.src; |
| 173 | + } |
| 174 | + |
| 175 | + const className = `vidCont ${props.inactive?'prtclk':''} ${props.className||''}`.trim() |
| 176 | + var dataset = {} |
| 177 | + Object.entries(props).forEach(([key, value]) => { |
| 178 | + if(key.includes("data-")){ |
| 179 | + dataset[key] = value |
| 180 | + } |
| 181 | + }); |
| 182 | + |
| 183 | + const handlePause = (e) => setPlay(false) |
| 184 | + const handlePlay = (e) => setPlay(true) |
| 185 | + |
| 186 | + const handleProg = (e)=>{ |
| 187 | + setProg(floor(e.playedSeconds)) |
| 188 | + setPerProg(e.played) |
| 189 | + } |
| 190 | + |
| 191 | + return ( |
| 192 | + <div className={className} id={props.id} |
| 193 | + onClick={props.onClick || (props.action && dispatchAction)} |
| 194 | + data-action={props.action} data-payload={props.payload} {...dataset} tabIndex="1"> |
| 195 | + {!props.playIcon && play && |
| 196 | + <Icon className="play-icon" mui="Pause" round w={48} onClick={handlePause}/>} |
| 197 | + {!props.playIcon && !play && |
| 198 | + <Icon className="play-icon opacity-100" mui="PlayArrow" round w={48} onClick={handlePlay}/>} |
| 199 | + {props.playIcon} |
| 200 | + <ReactPlayer className="react-video" |
| 201 | + url={src} |
| 202 | + width={props.w || "auto"} |
| 203 | + height={props.h || "auto"} |
| 204 | + controls={props.controls} playing={props.play || play} |
| 205 | + onPlay={props.onPlay || handlePlay} onPause={props.onPause || handlePause} |
| 206 | + onProgress={props.onProgress || handleProg} onEnded={props.onEnded || handlePause}/> |
| 207 | + {props.cstmctrl && ( |
| 208 | + <div className="video-control-container"> |
| 209 | + <span className="prog-text">{formatseconds(prog)}</span> |
| 210 | + <Slider size="small" |
| 211 | + className="video-progress" |
| 212 | + value={perProg*100} |
| 213 | + defaultValue={0} |
| 214 | + /> |
| 215 | + <span className="prog-text">{formatseconds(floor(prog/perProg))}</span> |
| 216 | + </div> |
| 217 | + )} |
| 218 | + </div> |
| 219 | + ) |
| 220 | +} |
| 221 | + |
145 | 222 | export const LazyComponent = ({ show, children }) => { |
146 | 223 | const [loaded, setLoad] = useState(false); |
147 | 224 |
|
|
0 commit comments