aboutsummaryrefslogtreecommitdiffstats
path: root/apps/Player/components
diff options
context:
space:
mode:
Diffstat (limited to 'apps/Player/components')
-rw-r--r--apps/Player/components/App.js107
-rw-r--r--apps/Player/components/Buttons.js34
-rw-r--r--apps/Player/components/Video.js32
3 files changed, 173 insertions, 0 deletions
diff --git a/apps/Player/components/App.js b/apps/Player/components/App.js
new file mode 100644
index 0000000..5879111
--- /dev/null
+++ b/apps/Player/components/App.js
@@ -0,0 +1,107 @@
+import styles from '../styles/Player.module.scss'
+import { useState, useEffect } from 'react'
+import useSettings from 'hooks/useSettings'
+import Video from './Video'
+import Buttons from './Buttons'
+import { Splash } from 'components'
+
+const App = ({ list }) => {
+ const { t } = useSettings()
+ const [current, setCurrent] = useState(null)
+ const [playlist, setPlaylist] = useState(null)
+ const [showPlaylist, setShowPlaylist] = useState(false)
+
+ useEffect(() => {
+ if (list) {
+ const { items, enqueue } = list
+
+ setPlaylist(
+ p => enqueue && p
+ ? p.some(x => items.some(y => x.id === y.id))
+ ? p
+ : [...p, ...items]
+ : items
+ )
+
+ if (enqueue) {
+ setShowPlaylist(true)
+ }
+ } else {
+ if (typeof window !== 'undefined') {
+ setPlaylist(JSON.parse(window.localStorage.getItem('playlist')))
+ }
+ }
+ }, [list])
+
+ useEffect(() => {
+ if (playlist) {
+ const { items, enqueue } = playlist
+
+ if (typeof window !== 'undefined' && playlist && playlist.length > 0) {
+ window.localStorage.setItem('playlist', JSON.stringify(enqueue ? [...playlist, ...items] : items))
+ setShowPlaylist(true)
+ }
+
+ if (current === null && list) {
+ setCurrent(
+ enqueue
+ ? playlist && playlist.length > 1
+ ? playlist.length - 1
+ : 0
+ : 0
+ )
+ }
+ }
+ }, [playlist])
+
+ if (!playlist) return <Splash />
+
+ return (
+ <>
+ <div className='window__submenu'>
+ <div>
+ <div
+ onClick={() => { setShowPlaylist(p => !p) }}
+ className={current ? 'active' : null}
+ >
+ {t('player_playlist_default')}
+ </div>
+ <div onClick={() => {}}>+</div>
+ <Buttons current={current} setCurrent={setCurrent} playlist={playlist} />
+ </div>
+ </div>
+ <div className={styles.player}>
+ <div>
+ {current !== null && (
+ <Video playlist={playlist} current={current} setCurrent={setCurrent} />
+ )}
+ </div>
+ <div style={showPlaylist ? {} : { transform: 'translateX(-110%)' }}>
+ <ul>
+ {
+ playlist && playlist.length > 0
+ ? (
+ playlist.map((item, i) => (
+ <li
+ onClick={() => { setCurrent(i) }}
+ className={current === i ? styles.activeItem : ''}
+ key={item.id}
+ >
+ <span>{(i + 1) + '.'}</span>
+ {item.title}
+ </li>
+ ))
+ )
+ : (
+ <li>{t('player_playlist_empty')}</li>
+ )
+ }
+ </ul>
+ <div onClick={() => setShowPlaylist(false)}>&lt;</div>
+ </div>
+ </div>
+ </>
+ )
+}
+
+export default App
diff --git a/apps/Player/components/Buttons.js b/apps/Player/components/Buttons.js
new file mode 100644
index 0000000..14452a0
--- /dev/null
+++ b/apps/Player/components/Buttons.js
@@ -0,0 +1,34 @@
+import { faStepForward, faStepBackward, faPlay, faStop } from '@fortawesome/free-solid-svg-icons'
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
+
+const Buttons = ({ current, setCurrent, playlist }) => (
+ <>
+ <span />
+ <div
+ className={current !== null && current > 0 ? '' : 'iconOff'}
+ onClick={() => { current !== null && current > 0 && setCurrent(c => c - 1) }}
+ >
+ <FontAwesomeIcon icon={faStepBackward} />
+ </div>
+ <div
+ className={current === null ? 'iconOff' : ''}
+ onClick={() => { current !== null && setCurrent(null) }}
+ >
+ <FontAwesomeIcon icon={faStop} />
+ </div>
+ <div
+ className={current === null ? '' : 'iconOff'}
+ onClick={() => { current === null && setCurrent(0) }}
+ >
+ <FontAwesomeIcon icon={faPlay} />
+ </div>
+ <div
+ className={current !== null && current < playlist.length - 1 ? '' : 'iconOff'}
+ onClick={() => { current !== null && current < playlist.length - 1 && setCurrent(c => c + 1) }}
+ >
+ <FontAwesomeIcon icon={faStepForward} />
+ </div>
+ </>
+)
+
+export default Buttons
diff --git a/apps/Player/components/Video.js b/apps/Player/components/Video.js
new file mode 100644
index 0000000..7152967
--- /dev/null
+++ b/apps/Player/components/Video.js
@@ -0,0 +1,32 @@
+import { useRef } from 'react'
+import Splash from 'components/Splash'
+
+const Video = ({ playlist, current, setCurrent }) => {
+ if (!playlist) return null
+
+ const videoEl = useRef()
+ const sources = playlist[current]?.sources
+
+ const handleEnd = () => {
+ setCurrent(current === playlist.length - 1 ? null : current + 1)
+ }
+
+ return (
+ sources
+ ? (
+ <video onEnded={handleEnd} ref={videoEl} key={playlist[current]?.id} controls autoPlay>
+ {
+ sources.map(s => (
+ <source src={s.url} type={s.mimeType} key={s.url} />
+ ))
+ }
+ Your browser does not support the video tag.
+ </video>
+ )
+ : (
+ <Splash />
+ )
+ )
+}
+
+export default Video