aboutsummaryrefslogtreecommitdiffstats
path: root/apps/Youtube/components/App.js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/Youtube/components/App.js')
-rw-r--r--apps/Youtube/components/App.js128
1 files changed, 69 insertions, 59 deletions
diff --git a/apps/Youtube/components/App.js b/apps/Youtube/components/App.js
index d902346..6130473 100644
--- a/apps/Youtube/components/App.js
+++ b/apps/Youtube/components/App.js
@@ -7,56 +7,64 @@ import { open } from 'helpers/windowActions'
import appList from 'configs/appList'
import Splash from 'components/Splash'
-const time = t => new Date(t * 1000).toISOString().substr(11, 8)
+const time = t => t ? new Date(t * 1000).toISOString().substr(11, 8) : '-'
const App = () => {
const { apps, setApps } = useApps()
const [results, setResults] = useState()
- const [searching, setSearching] = useState(false)
- const [sending, setSending] = useState(false)
+ const [loading, setLoading] = useState(false)
const [enqueue, setEnqueue] = useState(false)
- const [type, setType] = useState('youtube_videos')
+ const [type, setType] = useState('yt_video')
const { t } = useSettings()
- const handleSearch = async e => {
+ const handleSearch = e => {
e.preventDefault()
e.stopPropagation()
- setSearching(true)
- const quote = e.currentTarget.quote.value
+ setLoading(true)
+ const quote = [
+ e.currentTarget.quote.value,
+ { type: type === 'yt_music' ? 'music' : type.split('_')[1] }
+ ]
- const results = await fetchJson('/api/youtube/search', {
+ fetchJson('/api/youtube/search', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ quote })
})
-
- results?.videos && setResults(results.videos)
- setSearching(false)
+ .then(results => {
+ if (type === 'yt_live') {
+ results?.streams && setResults(results.streams)
+ } else if (type === 'yt_playlist') {
+ results?.playlists && setResults(results.playlists)
+ } else {
+ results?.videos && setResults(results.videos)
+ }
+ })
+ .catch(() => { console.log('Could not fetch results') })
+ .finally(() => { setLoading(false) })
}
- const handlePlay = async url => {
- setSending(true)
- const data = await fetchJson('/api/youtube/player', {
+ const fetchPlaylist = (id) => fetchJson(
+ '/api/youtube/playlist', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ url })
- })
-
- const list = {
- items: [{
- id: data.videoDetails.videoId,
- title: data.videoDetails.title,
- type: 'youtube-video',
- sources: data.formats.filter(v => v.hasAudio).sort((a, b) => a.bitrate > b.bitrate)
- }],
- enqueue
+ body: JSON.stringify({ id })
}
+ )
- apps && apps.length > 0 && apps.some(a => a && a.name === 'Player')
- ? setApps(prev => prev.map(a => a.name === 'Player' ? { ...a, props: { list } } : a))
- : open({ appName: 'Player', ...appList.Player }, setApps, { list })
+ const handlePlay = async (e, title, id) => {
+ e.stopPropagation()
+ setLoading(true)
+ const items = type === 'yt_playlist'
+ ? await fetchPlaylist(id)
+ .then(data => data.items.map(i => ({ title: i.title, id: i.id, type: i.isLive ? 'yt_live' : 'yt_video' })))
+ .catch(() => { console.log('Could not fetch playlist') })
+ : [{ title, id, type }]
- setSending(false)
+ apps && apps.length > 0 && apps.some(a => a && a.name === 'Player')
+ ? setApps(prev => prev.map(a => a.name === 'Player' ? { ...a, props: { list: { items, enqueue } } } : a))
+ : open({ appName: 'Player', ...appList.Player }, setApps, { list: { items, enqueue } })
+ setLoading(false)
}
return (
@@ -64,11 +72,9 @@ const App = () => {
<div className='window__submenu'>
<div>
{[
- 'youtube_videos',
- 'youtube_music',
- 'youtube_live',
- 'youtube_channels',
- 'youtube_playlists'
+ 'yt_video',
+ 'yt_live',
+ 'yt_playlist'
].map(y => (
<div
className={y === type ? 'active' : ''}
@@ -83,7 +89,7 @@ const App = () => {
className={enqueue ? '' : 'off'}
onClick={() => { setEnqueue(e => !e) }}
>
- {t('youtube_enqueue')}
+ {t('yt_enqueue')}
</div>
</div>
</div>
@@ -93,30 +99,34 @@ const App = () => {
<input type='submit' className='window__button' value={t('search')} />
</form>
<div className='window__scroll'>
- {
- searching
- ? (
- <Splash />
- )
- : (
- <ul>
- {
- results && results.length > 0 && results.map(r => (
- <li key={r.id} onClick={() => handlePlay(r.link)}>
- <img loading='lazy' src={r.thumbnail} width={96} height={72} />
- <p>{time(r.duration)}</p>
- <div>
- <p>{r.title}</p>
- <p>Views: {r.views}, uploaded: {r.uploaded || '-'}</p>
- <p>{r.channel?.name}</p>
- </div>
- </li>
- ))
- }
- {sending && <Splash fixed />}
- </ul>
- )
- }
+ <ul>
+ {
+ results && results.length > 0 && results.map(r => (
+ <li
+ key={r.id}
+ onClick={e => handlePlay(e, r.title, r.id)}
+ >
+ <img loading='lazy' src={r.thumbnail} width={96} height={72} />
+ {r.duration && <p>{time(r.duration)}</p>}
+ <div>
+ <p>{r.title}</p>
+ <p>{r.views
+ ? r.views + ' ' + t('yt_views')
+ : r.watching
+ ? r.watching + ' ' + t('yt_watching')
+ : r.videoCount
+ ? r.videoCount + t('yt_video_count')
+ : '-'}
+ {(r.views || r.watching) && r.uploaded && ', '}
+ {r.uploaded || ''}
+ </p>
+ <p>{r.channel?.name}</p>
+ </div>
+ </li>
+ ))
+ }
+ </ul>
+ {loading && <Splash fixed />}
</div>
</div>
</>