diff options
author | 2021-09-19 12:47:21 +0200 | |
---|---|---|
committer | 2021-09-19 12:47:21 +0200 | |
commit | 865c9cc345aa105714dfe3ccf1d1c0a9a6a75f7f (patch) | |
tree | 2dd4935ae03b084570c003eb0c004022e9a99de3 /apps/Player/components | |
parent | bb22276b9bdfdb23da313a5495dc4f3fcdb3bb09 (diff) | |
download | my_apps-865c9cc345aa105714dfe3ccf1d1c0a9a6a75f7f.tar.gz my_apps-865c9cc345aa105714dfe3ccf1d1c0a9a6a75f7f.tar.bz2 my_apps-865c9cc345aa105714dfe3ccf1d1c0a9a6a75f7f.zip |
youtube & player apps fixes
Diffstat (limited to 'apps/Player/components')
-rw-r--r-- | apps/Player/components/App.js | 82 | ||||
-rw-r--r-- | apps/Player/components/Buttons.js | 1 | ||||
-rw-r--r-- | apps/Player/components/Video.js | 63 |
3 files changed, 122 insertions, 24 deletions
diff --git a/apps/Player/components/App.js b/apps/Player/components/App.js index f7b0557..6633bc8 100644 --- a/apps/Player/components/App.js +++ b/apps/Player/components/App.js @@ -1,15 +1,20 @@ import styles from '../styles/Player.module.scss' import { useState, useEffect } from 'react' import useSettings from 'hooks/useSettings' +import useMediaQuery from 'hooks/useMediaQuery' import Video from './Video' import Buttons from './Buttons' import { Splash } from 'components' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faList, faTrashAlt, faCaretSquareRight, faInfinity, faAlignJustify } from '@fortawesome/free-solid-svg-icons' const App = ({ list }) => { const { t } = useSettings() + const smallDevice = useMediaQuery('(max-width: 40em)') const [current, setCurrent] = useState(null) const [playlist, setPlaylist] = useState(null) const [showPlaylist, setShowPlaylist] = useState(false) + const [details, setDetails] = useState({ show: false }) useEffect(() => { if (list) { @@ -40,16 +45,14 @@ const App = ({ 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)) + window.localStorage.setItem('playlist', JSON.stringify(playlist)) setShowPlaylist(true) } if (current === null && list) { setCurrent( - enqueue + list.enqueue ? playlist && playlist.length > 1 ? playlist.length - 1 : 0 @@ -59,7 +62,35 @@ const App = ({ list }) => { } }, [playlist]) - if (!playlist) return <Splash /> + useEffect(() => { + smallDevice && showPlaylist && setDetails(d => ({ ...d, show: false })) + }, [showPlaylist]) + + useEffect(() => { + smallDevice && details && details.show && setShowPlaylist(false) + }, [details && details.show]) + + const remove = (e, i) => { + e.stopPropagation() + if (current === i) { + setCurrent(null) + } + setPlaylist(p => p.filter((_, j) => j !== i)) + if (current > i) { + setCurrent(c => c - 1) + } + } + + if (!playlist) { + return ( + <> + <div className='window__submenu' /> + <div className={styles.player}> + <Splash /> + </div> + </> + ) + } return ( <> @@ -69,16 +100,24 @@ const App = ({ list }) => { onClick={() => { setShowPlaylist(p => !p) }} className={current ? 'active' : null} > - {t('player_playlist_default')} + <FontAwesomeIcon icon={faList} /> </div> - <div onClick={() => {}}>+</div> + <span /> <Buttons current={current} setCurrent={setCurrent} playlist={playlist} /> + <div onClick={() => { setDetails(d => ({ ...d, show: !d.show })) }}> + <FontAwesomeIcon icon={faAlignJustify} /> + </div> </div> </div> <div className={styles.player}> <div> - {current !== null && ( - <Video playlist={playlist} current={current} setCurrent={setCurrent} /> + {playlist && current !== null && playlist[current] && setDetails && ( + <Video + playlist={playlist} + current={current} + setCurrent={setCurrent} + setDetails={setDetails} + /> )} </div> <div style={showPlaylist ? {} : { transform: 'translateX(-110%)' }}> @@ -89,11 +128,19 @@ const App = ({ list }) => { playlist.map((item, i) => ( <li onClick={() => { setCurrent(i) }} - className={current === i ? styles.activeItem : ''} + className={current === i ? 'active' : ''} key={item.id} > + <FontAwesomeIcon + icon={item.type.split('_')[1] === 'live' + ? faInfinity + : faCaretSquareRight} + /> <span>{(i + 1) + '.'}</span> - {item.title} + <span>{item.title}</span> + <span onClick={e => remove(e, i)}> + <FontAwesomeIcon icon={faTrashAlt} /> + </span> </li> )) ) @@ -102,7 +149,18 @@ const App = ({ list }) => { ) } </ul> - <div onClick={() => setShowPlaylist(false)}><</div> + </div> + <div style={details.show ? {} : { transform: 'translateX(110%)' }}> + {details && ( + <div> + <pre> + {details.title} + </pre> + <pre> + {details.description} + </pre> + </div> + )} </div> </div> </> diff --git a/apps/Player/components/Buttons.js b/apps/Player/components/Buttons.js index 14452a0..efc8555 100644 --- a/apps/Player/components/Buttons.js +++ b/apps/Player/components/Buttons.js @@ -3,7 +3,6 @@ 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) }} diff --git a/apps/Player/components/Video.js b/apps/Player/components/Video.js index 7152967..7028f1f 100644 --- a/apps/Player/components/Video.js +++ b/apps/Player/components/Video.js @@ -1,25 +1,66 @@ -import { useRef } from 'react' +import { useState, useEffect, useRef } from 'react' import Splash from 'components/Splash' +import fetchJson from 'helpers/fetchJson' -const Video = ({ playlist, current, setCurrent }) => { - if (!playlist) return null - +const Video = ({ playlist, current, setCurrent, audioOnly = false, setDetails }) => { + const [data, setData] = useState(null) + const [loading, setLoading] = useState(null) const videoEl = useRef() - const sources = playlist[current]?.sources const handleEnd = () => { setCurrent(current === playlist.length - 1 ? null : current + 1) } + useEffect(() => { + setLoading(true) + if (current === null) { + setData(null) + setDetails(d => ({ ...d, show: false })) + } + + switch (playlist[current].type.split('_')[0]) { + case 'yt': + fetchJson('/api/youtube/video', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ id: playlist[current].id }) + }) + .then(v => { + setData({ + id: v.videoDetails.videoId, + formats: v.formats + .filter(v => !v.isHLS && v.hasAudio && (audioOnly ? !v.hasVideo : v.hasVideo)) + .sort((a, b) => audioOnly ? a.audioBitrate < b.audioBitrate : a.bitrate < b.bitrate) + }) + setDetails(d => ({ + ...d, + title: v.videoDetails.title, + description: v.videoDetails.description + })) + }) + .catch(() => console.log('error fetching video')) + .finally(() => setLoading(false)) + break + default: + } + }, [playlist && playlist[current].id]) + return ( - sources + data && !loading ? ( - <video onEnded={handleEnd} ref={videoEl} key={playlist[current]?.id} controls autoPlay> + <video + onEnded={handleEnd} + ref={videoEl} + key={data.id} + controls + autoPlay + style={audioOnly ? { backgroundImage: 'url(' + playlist[current].thumbnail + ')' } : {}} + > { - sources.map(s => ( - <source src={s.url} type={s.mimeType} key={s.url} /> - )) - } + data.formats.map(s => ( + <source src={s.url} type={s.mimeType} key={s.url} /> + )) + } Your browser does not support the video tag. </video> ) |