replaced ical library

This commit is contained in:
Benjamin Jones 2021-03-29 18:03:46 +02:00
parent f1bd7697fa
commit 5630705ea1
9 changed files with 101 additions and 63 deletions

View File

@ -3,6 +3,7 @@
"rules": {
"indent": ["error", 2],
"import/prefer-default-export": 0,
"react/require-default-props": 0
"react/require-default-props": 0,
"react/forbid-prop-types": 0
}
}

14
app.js
View File

@ -10,9 +10,8 @@ import { useEventStream } from './src/hooks/data'
import { useTimeout } from './src/hooks/timerHooks'
export default () => {
const [isPlaying, setIsPlaying] = useState(false)
const [currentVideo, setCurrentVideo] = useState(null)
const [streamIsLive, setStreamLive] = useState(false)
const [streamIsLive, setStreamIsLive] = useState(false)
const [infoActive, setInfoActive] = useState(false)
const [minLoadTimePassed, setMinTimeUp] = useState(false)
const { data, loading } = useEventStream()
@ -42,7 +41,7 @@ export default () => {
end: stream.end,
})
) {
setStreamLive(`${config.peertube_root}${stream.embedPath}`)
setStreamIsLive(true)
}
})
}
@ -51,14 +50,7 @@ export default () => {
return (
<div>
{currentVideo && !infoActive && minLoadTimePassed ? (
<Video
playing={isPlaying}
setPlaying={setIsPlaying}
src={`${config.peertube_root}${currentVideo.embedPath}`}
title={currentVideo.title}
org={currentVideo.channel.displayName}
setInfoActive={setInfoActive}
/>
<Video video={currentVideo} setInfoActive={setInfoActive} />
) : (
<Info
data={data}

View File

@ -18,6 +18,7 @@
"axios": "^0.21.1",
"date-fns": "^2.19.0",
"ical": "^0.8.0",
"ical.js": "^1.4.0",
"preact": "^10.5.12",
"prop-types": "^15.7.2",
"styled-components": "^5.2.1"
@ -35,4 +36,4 @@
"sass": "^1.32.8",
"scss": "^0.2.4"
}
}
}

View File

@ -24,6 +24,7 @@ export const ChatHeader = styled.div`
bottom: ${props => (props.chatIsOpen ? 'initial' : 0)};
top: ${props => (props.chatIsOpen ? '4px' : 'initial')};
border-radius: ${ui.borderRadius}px 0 0 0;
z-index: 2;
height: 32px;
box-sizing: border-box;

View File

@ -1,14 +1,24 @@
import { h } from 'preact'
import { useEffect, useRef, useState } from 'preact/hooks'
import { bool, func, string } from 'prop-types'
import {
bool,
func,
instanceOf,
number,
object,
shape,
string,
} from 'prop-types'
import 'regenerator-runtime/runtime'
import { PeerTubePlayer } from '@peertube/embed-api'
import Chat from '../Chat'
import Overlay from '../VideoOverlay'
import { VideoWrapper, Iframe } from './styles'
import config from '../../data/config'
const Video = ({ playing, setPlaying, src, title, org, setInfoActive }) => {
const Video = ({ video, org, setInfoActive }) => {
const [isPlaying, setPlaying] = useState(false)
const videoiFrame = useRef(null)
const overlayTimeout = useRef(null)
const [videoReady, setVideoReady] = useState(false)
@ -27,26 +37,40 @@ const Video = ({ playing, setPlaying, src, title, org, setInfoActive }) => {
setVideo()
}, [])
useEffect(() => {
const playVideo = () => {
const { current: player } = ptVideo
if (!videoReady) return
if (playing) {
setOverlayActiveState(false)
try {
player.play()
} catch (error) {
console.log({ error })
setOverlayActiveState(true)
setPlaying(false)
}
} else {
setPlaying(true)
try {
player.play()
} catch (error) {
console.log({ error })
setOverlayActiveState(true)
player.pause()
setPlaying(false)
}
}, [playing])
}
const pauseVideo = () => {
const { current: player } = ptVideo
setPlaying(false)
setOverlayActiveState(true)
try {
player.pause()
} catch (error) {
console.log({ error })
setPlaying(true)
setOverlayActiveState(false)
}
}
const toggleVideo = () => {
console.log('clicked')
if (isPlaying) {
pauseVideo()
} else {
playVideo()
}
}
const toggleFullscreen = () => {
if (!document.fullscreenElement) {
@ -58,15 +82,13 @@ const Video = ({ playing, setPlaying, src, title, org, setInfoActive }) => {
const handleKeyPress = keyCode => {
if (keyCode === 32) {
setPlaying(!playing)
// key == 'space'
toggleVideo()
}
if (keyCode === 70) {
// key == 'f'
toggleFullscreen()
}
// if (keyCode === 70 && isFullscreen) {
// console.log('exitFullscreen')
// exitFullscreen()
// }
}
useEffect(() => {
@ -90,22 +112,21 @@ const Video = ({ playing, setPlaying, src, title, org, setInfoActive }) => {
return (
<VideoWrapper
$active={overlayActive || !playing}
$active={overlayActive || !isPlaying}
onMouseMove={activateOverlay}
// ref={videoWrapperEl}
>
<Overlay
onClick={() => setPlaying(!playing)}
active={overlayActive || !playing}
title={title}
org={org}
onClick={toggleVideo}
active={overlayActive || !isPlaying}
title={video.title}
setInfoActive={setInfoActive}
/>
<Iframe
sandbox="allow-same-origin allow-scripts allow-popups"
src={`${src}?api=1&controls=false`}
src={`${config.peertube_root}${video.embedPath}?api=1&controls=false`}
frameborder="0"
allowfullscreen
allow="autoplay"
ref={videoiFrame}
/>
<Chat />
@ -114,9 +135,23 @@ const Video = ({ playing, setPlaying, src, title, org, setInfoActive }) => {
}
Video.propTypes = {
playing: bool,
setPlaying: func.isRequired,
src: string.isRequired,
video: shape({
account: object,
category: object,
channel: object,
description: string,
duration: number,
embedPath: string,
end: instanceOf(Date),
id: string,
language: object,
previewPath: string,
start: instanceOf(Date),
state: object,
title: 'Testing a livesteam :)',
videoUrl: string,
views: number,
}),
title: string.isRequired,
org: string,
}

View File

@ -9,15 +9,16 @@ export const VideoWrapper = styled.div`
bottom: 0;
left: 0;
right: 0;
/* pointer-events: none; */
cursor: ${props => (props.$active ? 'pointer' : 'none')};
`
export const Iframe = styled.iframe`
z-index: -1;
width: 100vw;
height: 100vh;
pointer-events: none;
`
export const Overlay = styled.div`
z-index: 2;
z-index: 1;
position: fixed;
height: 100vh;
width: 100vw;

View File

@ -5,11 +5,11 @@ import Logo from '../Logo'
import { H2, P } from '../Text'
import { InfoButton, OverlayWrapper, TopLeft } from './styles'
const VideoOverlay = ({ active, title, org, setInfoActive }) => (
const VideoOverlay = ({ active, title, org, setInfoActive, onClick }) => (
// const displayTitle = `${title}${org ? ` — ${org}` : ''}`
<Fragment>
<OverlayWrapper>
<OverlayWrapper onClick={onClick}>
<TopLeft $active={active}>
<Logo active={active} />
<P

View File

@ -7,7 +7,7 @@ export const OverlayWrapper = styled.div`
position: fixed;
height: 100vh;
width: 100vw;
pointer-events: none;
/* pointer-events: none; */
`
export const TopLeft = styled.div`
opacity: 0;

View File

@ -1,6 +1,6 @@
import { useEffect, useState, useRef } from 'preact/hooks'
import axios from 'axios'
import ical from 'ical'
import ICAL from 'ical.js'
import config from '../data/config'
export const useEventStream = () => {
@ -11,14 +11,24 @@ export const useEventStream = () => {
setLoading(true)
const { data: responseData } = await axios.get(`${config.calendar}`)
const calItems = Object.values(ical.parseICS(responseData))
.filter(feedItem => feedItem.type === 'VEVENT')
.sort((a, b) => new Date(a.start) - new Date(b.start))
const jCalData = ICAL.parse(responseData)
const comp = new ICAL.Component(jCalData)
const vevents = comp.getAllSubcomponents('vevent')
const calEvents = vevents
.map(vevent => new ICAL.Event(vevent))
.sort((a, b) => a.startDate.toJSDate() - b.startDate.toJSDate())
await Promise.all(
calItems.map(async calItem => {
if (calItem.url) {
const id = calItem.url.val.split('/').pop()
calEvents.map(async calItem => {
const url = calItem.component.getAllProperties('url')[0]
if (url) {
console.log('url', url)
const id = url
.getFirstValue()
.split('/')
.pop()
const {
data: {
account,
@ -31,11 +41,8 @@ export const useEventStream = () => {
views,
duration,
},
data: nesd,
} = await axios.get(`https://tv.undersco.re/api/v1/videos/${id}`)
console.log({ nesd })
const item = {
title: calItem.summary,
account,
@ -47,11 +54,11 @@ export const useEventStream = () => {
state,
previewPath,
views,
start: calItem.start,
end: calItem.end,
start: calItem.startDate.toJSDate(),
end: calItem.endDate.toJSDate(),
id,
duration,
videoUrl: calItem?.url?.val,
videoUrl: url.getFirstValue(),
}
setData(arr => [...arr, item])
}